test-report

Test coverage

To check test coverage you can run:

yarn coverage

You can see the coverage status at mainnet deployment here.

Impacted file tree graph

There’s also a pull request to increase the coverage, but it hasn’t been merged yet because it modifies some smart contracts (mostly removing unnecessary checks).

Test output

The following is the output of a complete test run, made on commit a1824dd8, from April 16th, 2021.

yarn run v1.22.11
$ hardhat test


  Contract: Access Control: Mosaic functions with the caller restricted to Mosaic contract(s)
    BorrowerOperations
      ✓ moveETHGainToTrove(): reverts when called by an account that is not StabilityPool
    TroveManager
      ✓ applyPendingRewards(): reverts when called by an account that is not BorrowerOperations
      ✓ updateRewardSnapshots(): reverts when called by an account that is not BorrowerOperations
      ✓ removeStake(): reverts when called by an account that is not BorrowerOperations
      ✓ updateStakeAndTotalStakes(): reverts when called by an account that is not BorrowerOperations
      ✓ closeTrove(): reverts when called by an account that is not BorrowerOperations
      ✓ addTroveOwnerToArray(): reverts when called by an account that is not BorrowerOperations
      ✓ setTroveStatus(): reverts when called by an account that is not BorrowerOperations
      ✓ increaseTroveColl(): reverts when called by an account that is not BorrowerOperations
      ✓ decreaseTroveColl(): reverts when called by an account that is not BorrowerOperations
      ✓ increaseTroveDebt(): reverts when called by an account that is not BorrowerOperations
      ✓ decreaseTroveDebt(): reverts when called by an account that is not BorrowerOperations
    ActivePool
      ✓ sendETH(): reverts when called by an account that is not BO nor TroveM nor SP
      ✓ increaseMoUSDDebt(): reverts when called by an account that is not BO nor TroveM
      ✓ decreaseMoUSDDebt(): reverts when called by an account that is not BO nor TroveM nor SP
      ✓ fallback(): reverts when called by an account that is not Borrower Operations nor Default Pool
    DefaultPool
      ✓ sendETHToActivePool(): reverts when called by an account that is not TroveManager
      ✓ increaseMoUSDDebt(): reverts when called by an account that is not TroveManager
      ✓ decreaseMoUSD(): reverts when called by an account that is not TroveManager
      ✓ fallback(): reverts when called by an account that is not the Active Pool
    StabilityPool
      ✓ offset(): reverts when called by an account that is not TroveManager
      ✓ fallback(): reverts when called by an account that is not the Active Pool
    MoUSDToken
      ✓ mint(): reverts when called by an account that is not BorrowerOperations
      ✓ burn(): reverts when called by an account that is not BO nor TroveM nor SP
      ✓ sendToPool(): reverts when called by an account that is not StabilityPool
      ✓ returnFromPool(): reverts when called by an account that is not TroveManager nor StabilityPool
    SortedTroves
      ✓ insert(): reverts when called by an account that is not BorrowerOps or TroveM
      ✓ remove(): reverts when called by an account that is not TroveManager
      ✓ reinsert(): reverts when called by an account that is neither BorrowerOps nor TroveManager
    LockupContract
      ✓ withdrawMSIC(): reverts when caller is not beneficiary (68ms)
    MSICStaking
      ✓ increaseF_MoUSD(): reverts when caller is not TroveManager
    MSICToken
      ✓ sendToMSICStaking(): reverts when caller is not the MSICSstaking (49ms)
    CommunityIssuance
      ✓ sendMSIC(): reverts when caller is not the StabilityPool
      ✓ issueMSIC(): reverts when caller is not the StabilityPool

  Contract: BorrowerOperations
    Without proxy
      ✓ addColl(): reverts when top-up would leave trove with ICR < MCR (278ms)
      ✓ addColl(): Increases the activePool REEF and raw ether balance by correct amount (203ms)
      ✓ addColl(), active Trove: adds the correct collateral amount to the Trove (194ms)
      ✓ addColl(), active Trove: Trove is in sortedList before and after (213ms)
      ✓ addColl(), active Trove: updates the stake and updates the total stakes (225ms)
      ✓ addColl(), active Trove: applies pending rewards and updates user's L_ETH, L_MoUSDDebt snapshots (736ms)
      ✓ addColl(), reverts if trove is non-existent or closed (831ms)
      ✓ addColl(): can add collateral in Recovery Mode (252ms)
      ✓ withdrawColl(): reverts when withdrawal would leave trove with ICR < MCR (349ms)
      ✓ withdrawColl(): reverts when calling address does not have active trove (328ms)
      ✓ withdrawColl(): reverts when system is in Recovery Mode (420ms)
      ✓ withdrawColl(): reverts when requested REEF withdrawal is > the trove's collateral (508ms)
      ✓ withdrawColl(): reverts when withdrawal would bring the user's ICR < MCR (313ms)
      ✓ withdrawColl(): reverts if system is in Recovery Mode (323ms)
      ✓ withdrawColl(): doesn’t allow a user to completely withdraw all collateral from their Trove (due to gas compensation) (352ms)
      ✓ withdrawColl(): leaves the Trove active when the user withdraws less than all the collateral (263ms)
      ✓ withdrawColl(): reduces the Trove's collateral by the correct amount (316ms)
      ✓ withdrawColl(): reduces ActivePool REEF and raw ether by correct amount (291ms)
      ✓ withdrawColl(): updates the stake and updates the total stakes (342ms)
      ✓ withdrawColl(): sends the correct amount of REEF to the user (289ms)
      ✓ withdrawColl(): applies pending rewards and updates user's L_ETH, L_MoUSDDebt snapshots (1205ms)
      ✓ withdrawMoUSD(): reverts when withdrawal would leave trove with ICR < MCR (516ms)
      ✓ withdrawMoUSD(): decays a non-zero base rate (1192ms)
      ✓ withdrawMoUSD(): reverts if max fee > 100% (668ms)
      ✓ withdrawMoUSD(): reverts if max fee < 0.5% in Normal mode (639ms)
      ✓ withdrawMoUSD(): reverts if fee exceeds max fee percentage (938ms)
      ✓ withdrawMoUSD(): succeeds when fee is less than max fee percentage (1272ms)
      ✓ withdrawMoUSD(): doesn't change base rate if it is already zero (1044ms)
      ✓ withdrawMoUSD(): lastFeeOpTime doesn't update if less time than decay interval has passed since the last fee operation (899ms)
      ✓ withdrawMoUSD(): borrower can't grief the baseRate and stop it decaying by issuing debt at higher frequency than the decay granularity (852ms)
      ✓ withdrawMoUSD(): borrowing at non-zero base rate sends MoUSD fee to MSIC staking contract (1004ms)
      ✓ withdrawMoUSD(): borrowing at non-zero base records the (drawn debt + fee) on the Trove struct (923ms)
      ✓ withdrawMoUSD(): Borrowing at non-zero base rate increases the MSIC staking contract MoUSD fees-per-unit-staked (986ms)
      ✓ withdrawMoUSD(): Borrowing at non-zero base rate sends requested amount to the user (1562ms)
      ✓ withdrawMoUSD(): Borrowing at zero base rate changes MoUSD fees-per-unit-staked (839ms)
      ✓ withdrawMoUSD(): Borrowing at zero base rate sends debt request to user (790ms)
      ✓ withdrawMoUSD(): reverts when calling address does not have active trove (370ms)
      ✓ withdrawMoUSD(): reverts when requested withdrawal amount is zero MoUSD (459ms)
      ✓ withdrawMoUSD(): reverts when system is in Recovery Mode (649ms)
      ✓ withdrawMoUSD(): reverts when withdrawal would bring the trove's ICR < MCR (347ms)
      ✓ withdrawMoUSD(): reverts when a withdrawal would cause the TCR of the system to fall below the CCR (439ms)
      ✓ withdrawMoUSD(): reverts if system is in Recovery Mode (312ms)
      ✓ withdrawMoUSD(): increases the Trove's MoUSD debt by the correct amount (208ms)
      ✓ withdrawMoUSD(): increases MoUSD debt in ActivePool by correct amount (230ms)
      ✓ withdrawMoUSD(): increases user MoUSDToken balance by correct amount (243ms)
      ✓ repayMoUSD(): reverts when repayment would leave trove with ICR < MCR (392ms)
      ✓ repayMoUSD(): Succeeds when it would leave trove with net debt >= minimum net debt (435ms)
      ✓ repayMoUSD(): reverts when it would leave trove with net debt < minimum net debt (256ms)
      ✓ repayMoUSD(): reverts when calling address does not have active trove (431ms)
      ✓ repayMoUSD(): reverts when attempted repayment is > the debt of the trove (418ms)
      ✓ repayMoUSD(): reduces the Trove's MoUSD debt by the correct amount (403ms)
      ✓ repayMoUSD(): decreases MoUSD debt in ActivePool by correct amount (406ms)
      ✓ repayMoUSD(): decreases user MoUSDToken balance by correct amount (404ms)
      ✓ repayMoUSD(): can repay debt in Recovery Mode (557ms)
      ✓ repayMoUSD(): Reverts if borrower has insufficient MoUSD balance to cover his debt repayment (1122ms)
      ✓ adjustTrove(): reverts when adjustment would leave trove with ICR < MCR (572ms)
      ✓ adjustTrove(): reverts if max fee < 0.5% in Normal mode (313ms)
      ✓ adjustTrove(): allows max fee < 0.5% in Recovery mode (577ms)
      ✓ adjustTrove(): decays a non-zero base rate (1218ms)
      ✓ adjustTrove(): doesn't decay a non-zero base rate when user issues 0 debt (935ms)
      ✓ adjustTrove(): doesn't change base rate if it is already zero (545ms)
      ✓ adjustTrove(): lastFeeOpTime doesn't update if less time than decay interval has passed since the last fee operation (819ms)
      ✓ adjustTrove(): borrower can't grief the baseRate and stop it decaying by issuing debt at higher frequency than the decay granularity (866ms)
      ✓ adjustTrove(): borrowing at non-zero base rate sends MoUSD fee to MSIC staking contract (889ms)
      ✓ adjustTrove(): borrowing at non-zero base records the (drawn debt + fee) on the Trove struct (1013ms)
      ✓ adjustTrove(): Borrowing at non-zero base rate increases the MSIC staking contract MoUSD fees-per-unit-staked (837ms)
      ✓ adjustTrove(): Borrowing at non-zero base rate sends requested amount to the user (895ms)
      ✓ adjustTrove(): Borrowing at zero base rate changes MoUSD balance of MSIC staking contract (783ms)
      ✓ adjustTrove(): Borrowing at zero base rate changes MSIC staking contract MoUSD fees-per-unit-staked (881ms)
      ✓ adjustTrove(): Borrowing at zero base rate sends total requested MoUSD to the user (783ms)
      ✓ adjustTrove(): reverts when calling address has no active trove (416ms)
      ✓ adjustTrove(): reverts in Recovery Mode when the adjustment would reduce the TCR (654ms)
      ✓ adjustTrove(): collateral withdrawal reverts in Recovery Mode (370ms)
      ✓ adjustTrove(): debt increase that would leave ICR < 150% reverts in Recovery Mode (497ms)
      ✓ adjustTrove(): debt increase that would reduce the ICR reverts in Recovery Mode (596ms)
      ✓ adjustTrove(): A trove with ICR < CCR in Recovery Mode can adjust their trove to ICR > CCR (599ms)
      ✓ adjustTrove(): A trove with ICR > CCR in Recovery Mode can improve their ICR (524ms)
      ✓ adjustTrove(): debt increase in Recovery Mode charges no fee (543ms)
      ✓ adjustTrove(): reverts when change would cause the TCR of the system to fall below the CCR (587ms)
      ✓ adjustTrove(): reverts when MoUSD repaid is > debt of the trove (451ms)
      ✓ adjustTrove(): reverts when attempted REEF withdrawal is >= the trove's collateral (683ms)
      ✓ adjustTrove(): reverts when change would cause the ICR of the trove to fall below the MCR (521ms)
      ✓ adjustTrove(): With 0 coll change, doesnt change borrower's coll or ActivePool coll (289ms)
      ✓ adjustTrove(): With 0 debt change, doesnt change borrower's debt or ActivePool debt (354ms)
      ✓ adjustTrove(): updates borrower's debt and coll with an increase in both (558ms)
      ✓ adjustTrove(): updates borrower's debt and coll with a decrease in both (553ms)
      ✓ adjustTrove(): updates borrower's  debt and coll with coll increase, debt decrease (375ms)
      ✓ adjustTrove(): updates borrower's debt and coll with coll decrease, debt increase (346ms)
      ✓ adjustTrove(): updates borrower's stake and totalStakes with a coll increase (385ms)
      ✓ adjustTrove():  updates borrower's stake and totalStakes with a coll decrease (553ms)
      ✓ adjustTrove(): changes MoUSDToken balance by the requested decrease (529ms)
      ✓ adjustTrove(): changes MoUSDToken balance by the requested increase (577ms)
      ✓ adjustTrove(): Changes the activePool REEF and raw ether balance by the requested decrease (1371ms)
      ✓ adjustTrove(): Changes the activePool REEF and raw ether balance by the amount of REEF sent (548ms)
      ✓ adjustTrove(): Changes the MoUSD debt in ActivePool by requested decrease (541ms)
      ✓ adjustTrove(): Changes the MoUSD debt in ActivePool by requested increase (397ms)
      ✓ adjustTrove(): new coll = 0 and new debt = 0 is not allowed, as gas compensation still counts toward ICR (385ms)
      ✓ adjustTrove(): Reverts if requested debt increase and amount is zero (292ms)
      ✓ adjustTrove(): Reverts if requested coll withdrawal and ether is sent (288ms)
      ✓ adjustTrove(): Reverts if it’s zero adjustment (137ms)
      ✓ adjustTrove(): Reverts if requested coll withdrawal is greater than trove's collateral (402ms)
      ✓ adjustTrove(): Reverts if borrower has insufficient MoUSD balance to cover his debt repayment (496ms)
      ✓ Internal _adjustTrove(): reverts when op is a withdrawal and _borrower param is not the msg.sender (475ms)
      ✓ closeTrove(): reverts when it would lower the TCR below CCR (471ms)
      ✓ closeTrove(): reverts when calling address does not have active trove (221ms)
      ✓ closeTrove(): reverts when system is in Recovery Mode (746ms)
      ✓ closeTrove(): reverts when trove is the only one in the system (497ms)
      ✓ closeTrove(): reduces a Trove's collateral to zero (582ms)
      ✓ closeTrove(): reduces a Trove's debt to zero (398ms)
      ✓ closeTrove(): sets Trove's stake to zero (504ms)
      ✓ closeTrove(): zero's the troves reward snapshots (1002ms)
      ✓ closeTrove(): sets trove's status to closed and removes it from sorted troves list (526ms)
      ✓ closeTrove(): reduces ActivePool REEF and raw ether by correct amount (466ms)
      ✓ closeTrove(): reduces ActivePool debt by correct amount (522ms)
      ✓ closeTrove(): updates the the total stakes (790ms)
      ✓ closeTrove(): sends the correct amount of REEF to the user (390ms)
      ✓ closeTrove(): subtracts the debt of the closed Trove from the Borrower's MoUSDToken balance (405ms)
      ✓ closeTrove(): applies pending rewards (1267ms)
      ✓ closeTrove(): reverts if borrower has insufficient MoUSD balance to repay his entire debt (347ms)
      ✓ openTrove(): emits a TroveUpdated event with the correct collateral and debt (820ms)
      ✓ openTrove(): Opens a trove with net debt >= minimum net debt (235ms)
      ✓ openTrove(): reverts if net debt < minimum net debt (294ms)
      ✓ openTrove(): decays a non-zero base rate (959ms)
      ✓ openTrove(): doesn't change base rate if it is already zero (911ms)
      ✓ openTrove(): lastFeeOpTime doesn't update if less time than decay interval has passed since the last fee operation (953ms)
      ✓ openTrove(): reverts if max fee > 100% (56ms)
      ✓ openTrove(): reverts if max fee < 0.5% in Normal mode (85ms)
      ✓ openTrove(): allows max fee < 0.5% in Recovery Mode (409ms)
      ✓ openTrove(): reverts if fee exceeds max fee percentage (747ms)
      ✓ openTrove(): succeeds when fee is less than max fee percentage (930ms)
      ✓ openTrove(): borrower can't grief the baseRate and stop it decaying by issuing debt at higher frequency than the decay granularity (965ms)
      ✓ openTrove(): borrowing at non-zero base rate sends MoUSD fee to MSIC staking contract (923ms)
      ✓ openTrove(): borrowing at non-zero base records the (drawn debt + fee  + liq. reserve) on the Trove struct (865ms)
      ✓ openTrove(): Borrowing at non-zero base rate increases the MSIC staking contract MoUSD fees-per-unit-staked (794ms)
      ✓ openTrove(): Borrowing at non-zero base rate sends requested amount to the user (832ms)
      ✓ openTrove(): Borrowing at zero base rate changes the MSIC staking contract MoUSD fees-per-unit-staked (602ms)
      ✓ openTrove(): Borrowing at zero base rate charges minimum fee (316ms)
      ✓ openTrove(): reverts when system is in Recovery Mode and ICR < CCR (320ms)
      ✓ openTrove(): reverts when trove ICR < MCR (536ms)
      ✓ openTrove(): reverts when opening the trove would cause the TCR of the system to fall below the CCR (367ms)
      ✓ openTrove(): reverts if trove is already active (679ms)
      ✓ openTrove(): Can open a trove with ICR >= CCR when system is in Recovery Mode (499ms)
      ✓ openTrove(): Reverts opening a trove with min debt when system is in Recovery Mode (324ms)
      ✓ openTrove(): creates a new Trove and assigns the correct collateral and debt amount (127ms)
      ✓ openTrove(): adds Trove owner to TroveOwners array (136ms)
      ✓ openTrove(): creates a stake and adds it to total stakes (281ms)
      ✓ openTrove(): inserts Trove to Sorted Troves list (370ms)
      ✓ openTrove(): Increases the activePool REEF and raw ether balance by correct amount (294ms)
      ✓ openTrove(): records up-to-date initial snapshots of L_ETH and L_MoUSDDebt (639ms)
      ✓ openTrove(): allows a user to open a Trove, then close it, then re-open it (687ms)
      ✓ openTrove(): increases the Trove's MoUSD debt by the correct amount (129ms)
      ✓ openTrove(): increases MoUSD debt in ActivePool by the debt of the trove (162ms)
      ✓ openTrove(): increases user MoUSDToken balance by correct amount (85ms)
      ✓ getCompositeDebt(): returns debt + gas comp
      ✓ closeTrove(): fails if owner cannot receive REEF (440ms)
      getNewICRFromTroveChange() returns the correct ICR
        ✓ collChange = 0, debtChange = 0
        ✓ collChange = 0, debtChange is positive
        ✓ collChange = 0, debtChange is negative
        ✓ collChange is positive, debtChange is 0
        ✓ collChange is negative, debtChange is 0
        ✓ collChange is negative, debtChange is negative
        ✓ collChange is positive, debtChange is positive
        ✓ collChange is positive, debtChange is negative
        ✓ collChange is negative, debtChange is positive
      getNewTCRFromTroveChange() returns the correct TCR
        ✓ collChange = 0, debtChange = 0 (248ms)
        ✓ collChange = 0, debtChange is positive (630ms)
        ✓ collChange = 0, debtChange is negative (327ms)
        ✓ collChange is positive, debtChange is 0 (328ms)
        ✓ collChange is negative, debtChange is 0 (407ms)
        ✓ collChange is negative, debtChange is negative (605ms)
        ✓ collChange is positive, debtChange is positive (601ms)
        ✓ collChange is positive, debtChange is negative (609ms)
        ✓ collChange is negative, debtChange is positive (381ms)

  Contract: CollSurplusPool
    ✓ CollSurplusPool::getETH(): Returns the REEF balance of the CollSurplusPool after redemption (2203ms)
    ✓ CollSurplusPool: claimColl(): Reverts if caller is not Borrower Operations
    ✓ CollSurplusPool: claimColl(): Reverts if nothing to claim
    ✓ CollSurplusPool: claimColl(): Reverts if owner cannot receive REEF surplus (723ms)
    ✓ CollSurplusPool: reverts trying to send REEF to it
    ✓ CollSurplusPool: accountSurplus: reverts if caller is not Trove Manager

  Contract: Deployment script - Sets correct contract addresses dependencies after deployment
    ✓ Sets the correct PriceFeed address in TroveManager
    ✓ Sets the correct MoUSDToken address in TroveManager
    ✓ Sets the correct SortedTroves address in TroveManager
    ✓ Sets the correct BorrowerOperations address in TroveManager
    ✓ Sets the correct ActivePool address in TroveManager
    ✓ Sets the correct DefaultPool address in TroveManager
    ✓ Sets the correct StabilityPool address in TroveManager
    ✓ Sets the correct MSICStaking address in TroveManager
    ✓ Sets the correct StabilityPool address in ActivePool
    ✓ Sets the correct DefaultPool address in ActivePool (133ms)
    ✓ Sets the correct BorrowerOperations address in ActivePool
    ✓ Sets the correct TroveManager address in ActivePool
    ✓ Sets the correct ActivePool address in StabilityPool
    ✓ Sets the correct BorrowerOperations address in StabilityPool
    ✓ Sets the correct MoUSDToken address in StabilityPool
    ✓ Sets the correct TroveManager address in StabilityPool
    ✓ Sets the correct TroveManager address in DefaultPool
    ✓ Sets the correct ActivePool address in DefaultPool
    ✓ Sets the correct TroveManager address in SortedTroves
    ✓ Sets the correct BorrowerOperations address in SortedTroves
    ✓ Sets the correct TroveManager address in BorrowerOperations
    ✓ Sets the correct PriceFeed address in BorrowerOperations
    ✓ Sets the correct SortedTroves address in BorrowerOperations
    ✓ Sets the correct ActivePool address in BorrowerOperations
    ✓ Sets the correct DefaultPool address in BorrowerOperations
    ✓ Sets the correct MSICStaking address in BorrowerOperations
    ✓ Sets the correct MSICToken address in MSICStaking
    ✓ Sets the correct ActivePool address in MSICStaking
    ✓ Sets the correct ActivePool address in MSICStaking
    ✓ Sets the correct ActivePool address in MSICStaking
    ✓ Sets the correct BorrowerOperations address in MSICStaking
    ✓ Sets the correct CommunityIssuance address in MSICToken
    ✓ Sets the correct MSICStaking address in MSICToken
    ✓ Sets the correct LockupContractFactory address in MSICToken
    ✓ Sets the correct MSICToken address in LockupContractFactory
    ✓ Sets the correct MSICToken address in CommunityIssuance
    ✓ Sets the correct StabilityPool address in CommunityIssuance

  Contract: DefaultPool
    ✓ sendETHToActivePool(): fails if receiver cannot receive REEF

  Contract: Fee arithmetic tests
    ✓ minutesPassedSinceLastFeeOp(): returns minutes passed for no time increase (197ms)
    ✓ minutesPassedSinceLastFeeOp(): returns minutes passed between time of last fee operation and current block.timestamp, rounded down to nearest minutes (982ms)
    ✓ decayBaseRateFromBorrowing(): returns the initial base rate for no time increase
    ✓ decayBaseRateFromBorrowing(): returns the initial base rate for less than one minute passed  (386ms)
    ✓ decayBaseRateFromBorrowing(): returns correctly decayed base rate, for various durations. Initial baseRate = 0.01 (2908ms)
    ✓ decayBaseRateFromBorrowing(): returns correctly decayed base rate, for various durations. Initial baseRate = 0.1 (3951ms)
    ✓ decayBaseRateFromBorrowing(): returns correctly decayed base rate, for various durations. Initial baseRate = 0.34539284 (3651ms)
    ✓ decayBaseRateFromBorrowing(): returns correctly decayed base rate, for various durations. Initial baseRate = 0.9976 (4377ms)
    Basic exponentiation
      ✓ decPow(): for exponent = 0, returns 1, regardless of base (42ms)
      ✓ decPow(): for exponent = 1, returns base, regardless of base (86ms)
      ✓ decPow(): for base = 0, returns 0 for any exponent other than 0 (238ms)
      ✓ decPow(): for base = 1, returns 1 for any exponent (179ms)
      ✓ decPow(): for exponent = 2, returns the square of the base (86ms)
      ✓ decPow(): correct output for various bases and exponents (2032ms)
      ✓ decPow(): abs. error < 1e-9 for exponent = 7776000 (seconds in three months) (8459ms)
      ✓ decPow(): abs. error < 1e-9 for exponent = 2592000 (seconds in one month) (4815ms)
      ✓ decPow(): abs. error < 1e-9 for exponent = 43200 (minutes in one month) (4387ms)
      ✓ decPow(): abs. error < 1e-9 for exponent = 525600 (minutes in one year) (4454ms)
      ✓ decPow(): abs. error < 1e-9 for exponent = 2628000 (minutes in five years) (4724ms)
      ✓ decPow(): abs. error < 1e-9 for exponent = minutes in ten years (3847ms)
      ✓ decPow(): abs. error < 1e-9 for exponent = minutes in one hundred years (5802ms)
      - decPow(): overflow test: doesn't overflow for exponent = minutes in 1000 years

  Contract: Gas compensation tests
    ✓ _getCollGasCompensation(): returns the 0.5% of collaterall if it is < $10 in value
    ✓ _getCollGasCompensation(): returns 0.5% of collaterall when 0.5% of collateral < $10 in value
    ✓ getCollGasCompensation(): returns 0.5% of collaterall when 0.5% of collateral = $10 in value
    ✓ getCollGasCompensation(): returns 0.5% of collaterall when 0.5% of collateral = $10 in value (72ms)
    ✓ _getCompositeDebt(): returns (debt + 50) when collateral < $10 in value
    ✓ getCompositeDebt(): returns (debt + 50) collateral = $10 in value
    ✓ getCompositeDebt(): returns (debt + 50) when 0.5% of collateral > $10 in value (52ms)
    ✓ getCurrentICR(): Incorporates virtual debt, and returns the correct ICR for new troves (1147ms)
    ✓ Gas compensation from pool-offset liquidations. All collateral paid as compensation (1340ms)
    ✓ gas compensation from pool-offset liquidations: 0.5% collateral < $10 in value. Compensates $10 worth of collateral, liquidates the remainder (1199ms)
    ✓ gas compensation from pool-offset liquidations: 0.5% collateral > $10 in value. Compensates 0.5% of  collateral, liquidates the remainder (1333ms)
TCR: 238.086389539884110295
TCR: 11.892415157517211309
    ✓ Gas compensation from pool-offset liquidations. Liquidation event emits the correct gas compensation and total liquidated coll and debt (1541ms)
    ✓ gas compensation from pool-offset liquidations. Liquidation event emits the correct gas compensation and total liquidated coll and debt (1498ms)
    ✓ gas compensation from pool-offset liquidations: 0.5% collateral > $10 in value. Liquidation event emits the correct gas compensation and total liquidated coll and debt (1547ms)
    ✓ liquidateTroves(): full offset.  Compensates the correct amount, and liquidates the remainder (1810ms)
    ✓ liquidateTroves(): full redistribution. Compensates the correct amount, and liquidates the remainder (1312ms)
    ✓ liquidateTroves(): full offset. Liquidation event emits the correct gas compensation and total liquidated coll and debt (1551ms)
    ✓ liquidateTroves(): full redistribution. Liquidation event emits the correct gas compensation and total liquidated coll and debt (1790ms)
    ✓ Trove ordering: same collateral, decreasing debt. Price successively increases. Troves should maintain ordering by ICR (1647ms)
    ✓ Trove ordering: increasing collateral, constant debt. Price successively increases. Troves should maintain ordering by ICR (3885ms)
    ✓ Trove ordering: Constant raw collateral ratio (excluding virtual debt). Price successively increases. Troves should maintain ordering by ICR (2042ms)

  Contract: MSIC Token
    ✓ balanceOf(): gets the balance of the account (43ms)
    ✓ totalSupply(): gets the total supply
    ✓ name(): returns the token's name
    ✓ symbol(): returns the token's symbol
    ✓ version(): returns the token contract's version
    ✓ decimal(): returns the number of decimal digits used
    ✓ allowance(): returns an account's spending allowance for another account's balance (48ms)
    ✓ approve(): approves an account to spend the specified ammount (47ms)
    ✓ approve(): reverts when spender param is address(0) (52ms)
    ✓ approve(): reverts when owner param is address(0) (60ms)
    ✓ transferFrom(): successfully transfers from an account which it is approved to transfer from (123ms)
    ✓ transfer(): increases the recipient's balance by the correct amount (42ms)
    ✓ transfer(): reverts when amount exceeds sender's balance (56ms)
    ✓ transfer(): transfer to a blacklisted address reverts (204ms)
    ✓ transfer(): transfer to or from the zero-address reverts (49ms)
    ✓ mint(): issues correct amount of tokens to the given address
    ✓ mint(): reverts when beneficiary is address(0)
    ✓ increaseAllowance(): increases an account's allowance by the correct amount
    ✓ decreaseAllowance(): decreases an account's allowance by the correct amount
    ✓ sendToMSICStaking(): changes balances of MSICStaking and calling account by the correct amounts (48ms)
    ✓ Initializes PERMIT_TYPEHASH correctly
    ✓ Initializes DOMAIN_SEPARATOR correctly
    ✓ Initial nonce for a given address is 0
    ✓ permit(): permits and emits an Approval event (replay protected) (88ms)
    ✓ permit(): fails with expired deadline
    ✓ permit(): fails with the wrong signature (46ms)

  Contract: HintHelpers
    ✓ setup: makes accounts with nominal ICRs increasing by 1% consecutively (76ms)
    ✓ getApproxHint(): returns the address of a Trove within sqrt(length) positions of the correct insert position (1441ms)
    ✓ getApproxHint(): returns the head of the list if the CR is the max uint256 value (270ms)
    ✓ getApproxHint(): returns the tail of the list if the CR is lower than ICR of any Trove (321ms)
    ✓ computeNominalCR()

  Contract: Deploying and funding One Year Lockup Contracts
    Deploying LCs
      ✓ MSIC Deployer can deploy LCs through the Factory (121ms)
      ✓ Anyone can deploy LCs through the Factory (71ms)
      ✓ MSIC Deployer can deploy LCs directly (43ms)
      ✓ Anyone can deploy LCs directly (43ms)
      ✓ LC deployment stores the beneficiary's address in the LC (1806ms)
      ✓ LC deployment through the Factory registers the LC in the Factory (99ms)
      ✓ LC deployment through the Factory records the LC contract address and deployer as a k-v pair in the Factory (90ms)
      ✓ LC deployment through the Factory sets the unlockTime in the LC (52ms)
      ✓ Direct deployment of LC sets the unlockTime in the LC (55ms)
      ✓ LC deployment through the Factory reverts when the unlockTime is < 1 year from system deployment (50ms)
      ✓ Direct deployment of LC reverts when the unlockTime is < 1 year from system deployment (54ms)
    Funding LCs
      ✓ MSIC transfer from MSIC deployer to their deployed LC increases the MSIC balance of the LC (397ms)
      ✓ MSIC Multisig can transfer MSIC to LCs deployed through the factory by anyone (168ms)
    Withdrawal attempts on funded, inactive LCs immediately after funding
      ✓ Beneficiary can't withdraw from their funded LC (346ms)
      ✓ MSIC multisig can't withraw from a LC which it funded (271ms)
      ✓ No one can withraw from a LC (78ms)

  Contract: Deploying the MSIC contracts: LCF, CI, MSICStaking, and MSICToken 
    CommunityIssuance deployment
      ✓ Stores the deployer's address
    MSICStaking deployment
      ✓ Stores the deployer's address
    MSICToken deployment
      ✓ Stores the multisig's address
      ✓ Stores the CommunityIssuance address
      ✓ Stores the LockupContractFactory address
      ✓ Mints the correct MSIC amount to the multisig's address: (64.66 million)
      ✓ Mints the correct MSIC amount to the CommunityIssuance contract address: 32 million
      ✓ Mints the correct MSIC amount to the bountyAddress EOA: 2 million
      ✓ Mints the correct MSIC amount to the lpRewardsAddress EOA: 1.33 million
    Community Issuance deployment
      ✓ Stores the deployer's address
      ✓ Has a supply cap of 32 million
      ✓ Mosaic AG can set addresses if CI's MSIC balance is equal or greater than 32 million  (393ms)
      ✓ Mosaic AG can't set addresses if CI's MSIC balance is < 32 million  (367ms)
    Connecting MSICToken to LCF, CI and MSICStaking
      ✓ sets the correct MSICToken address in MSICStaking (1866ms)
      ✓ sets the correct MSICToken address in LockupContractFactory
      ✓ sets the correct MSICToken address in CommunityIssuance (203ms)

  Contract: During the initial lockup period
    MSIC transfer during first year after MSIC deployment
      ✓ Mosaic multisig can not transfer MSIC to a LC that was deployed directly (105ms)
      ✓ Mosaic multisig can not transfer to an EOA or Mosaic system contracts (302ms)
      ✓ Mosaic multisig can not approve any EOA or Mosaic system contract to spend their MSIC (546ms)
      ✓ Mosaic multisig can not increaseAllowance for any EOA or Mosaic contract (285ms)
      ✓ Mosaic multisig can not decreaseAllowance for any EOA or Mosaic contract (338ms)
      ✓ Mosaic multisig can not be the sender in a transferFrom() call
      ✓ Mosaic multisig can not stake their MSIC in the staking contract
      ✓ Anyone (other than Mosaic multisig) can transfer MSIC to LCs deployed by anyone through the Factory (359ms)
      ✓ Anyone (other than Mosaic multisig) can transfer MSIC to LCs deployed by anyone directly (141ms)
      ✓ Anyone (other than mosaic multisig) can transfer to an EOA (106ms)
      ✓ Anyone (other than mosaic multisig) can approve any EOA or to spend their MSIC
      ✓ Anyone (other than mosaic multisig) can increaseAllowance for any EOA or Mosaic contract (244ms)
      ✓ Anyone (other than mosaic multisig) can decreaseAllowance for any EOA or Mosaic contract (693ms)
      ✓ Anyone (other than mosaic multisig) can be the sender in a transferFrom() call (62ms)
      ✓ Anyone (other than mosaic AG) can stake their MSIC in the staking contract
    Lockup Contract Factory negative tests
      ✓ deployLockupContract(): reverts when MSIC token address is not set (197ms)
    Transferring MSIC to LCs
      ✓ Mosaic multisig can transfer MSIC (vesting) to lockup contracts they deployed (198ms)
      ✓ Mosaic multisig can transfer MSIC to lockup contracts deployed by anyone (1798ms)
    Deploying new LCs
      ✓ MSIC Deployer can deploy LCs through the Factory (46ms)
      ✓ Mosaic multisig can deploy LCs through the Factory
      ✓ Anyone can deploy LCs through the Factory (80ms)
      ✓ MSIC Deployer can deploy LCs directly (44ms)
      ✓ Mosaic multisig can deploy LCs directly (45ms)
      ✓ Anyone can deploy LCs directly (46ms)
      ✓ Anyone can deploy LCs with unlockTime = one year from deployment, directly and through factory (102ms)
      ✓ Anyone can deploy LCs with unlockTime > one year from deployment, directly and through factory (187ms)
      ✓ No one can deploy LCs with unlockTime < one year from deployment, directly or through factory (100ms)
      Withdrawal Attempts on LCs before unlockTime has passed 
        ✓ Mosaic multisig can't withdraw from a funded LC they deployed for another beneficiary through the Factory before the unlockTime
        ✓ Mosaic multisig can't withdraw from a funded LC that someone else deployed before the unlockTime (52ms)
        ✓ Beneficiary can't withdraw from their funded LC before the unlockTime (219ms)
        ✓ No one can withdraw from a beneficiary's funded LC before the unlockTime (475ms)

  Contract: After the initial lockup period has passed
    Deploying new LCs
      ✓ MSIC Deployer can deploy new LCs
      ✓ Anyone can deploy new LCs (42ms)
      ✓ Anyone can deploy new LCs with unlockTime in the past (65ms)
      ✓ Anyone can deploy new LCs with unlockTime in the future (46ms)
    Beneficiary withdrawal from initial LC
      ✓ A beneficiary can withdraw their full entitlement from their LC (256ms)
      ✓ A beneficiary on a vesting schedule can withdraw their total vested amount from their LC (155ms)
      ✓ Beneficiaries can withraw full MSIC balance of LC if it has increased since lockup period ended (234ms)
    Withdrawal attempts from LCs by non-beneficiaries
      ✓ MSIC Multisig can't withdraw from a LC they deployed through the Factory
      ✓ MSIC Multisig can't withdraw from a LC that someone else deployed
      ✓ Non-beneficiaries cannot withdraw from a LC (189ms)
    Transferring MSIC
      ✓ MSIC multisig can transfer MSIC to LCs they deployed (176ms)
      ✓ MSIC multisig can transfer tokens to LCs deployed by anyone (104ms)
      ✓ MSIC multisig can transfer MSIC directly to any externally owned account (141ms)
      ✓ Anyone can transfer MSIC to LCs deployed by anyone (179ms)
      ✓ Anyone can transfer to an EOA (421ms)
      ✓ Anyone can approve any EOA to spend their MSIC
      ✓ Anyone can increaseAllowance for any EOA or Mosaic contract (2441ms)
      ✓ Anyone can decreaseAllowance for any EOA or Mosaic contract (1034ms)
      ✓ Anyone can be the sender in a transferFrom() call (101ms)
      ✓ Anyone can stake their MSIC in the staking contract (55ms)
    Withdrawal Attempts on new LCs before unlockTime has passed
      ✓ MSIC Deployer can't withdraw from a funded LC they deployed for another beneficiary through the Factory, before the unlockTime (44ms)
      ✓ MSIC Deployer can't withdraw from a funded LC that someone else deployed, before the unlockTime (448ms)
      ✓ Beneficiary can't withdraw from their funded LC, before the unlockTime (284ms)
      ✓ No one can withdraw from a beneficiary's funded LC, before the unlockTime (443ms)
    Withdrawals from new LCs after unlockTime has passed
      ✓ MSIC Deployer can't withdraw from a funded LC they deployed for another beneficiary through the Factory, after the unlockTime (100ms)
      ✓ MSIC multisig can't withdraw from a funded LC when they are not the beneficiary, after the unlockTime (529ms)
      ✓ Beneficiary can withdraw from their funded LC, after the unlockTime (97ms)
      ✓ Non-beneficiaries can't withdraw from a beneficiary's funded LC, after the unlockTime (226ms)

  Contract: MosaicMath
    ✓ max works if a > b
    ✓ max works if a = b
    ✓ max works if a < b

  Contract: MosaicSafeMath128Tester
    ✓ add(): reverts if overflows
    ✓ sub(): reverts if underflows

  Contract: MSIC community issuance arithmetic tests
issuance fraction before: 949066037374286
issuance fraction after: 949066037374286
    ✓ getCumulativeIssuanceFraction(): fraction doesn't increase if less than a minute has passed (45ms)
    ✓ Cumulative issuance fraction is 0.0000013 after a minute
    ✓ Cumulative issuance fraction is 0.000079 after an hour
    ✓ Cumulative issuance fraction is 0.0019 after a day
    ✓ Cumulative issuance fraction is 0.013 after a week (283ms)
    ✓ Cumulative issuance fraction is 0.055 after a month (38ms)
    ✓ Cumulative issuance fraction is 0.16 after 3 months
    ✓ Cumulative issuance fraction is 0.29 after 6 months (38ms)
    ✓ Cumulative issuance fraction is 0.5 after a year
    ✓ Cumulative issuance fraction is 0.75 after 2 years
    ✓ Cumulative issuance fraction is 0.875 after 3 years (44ms)
    ✓ Cumulative issuance fraction is 0.9375 after 4 years (50ms)
    ✓ Cumulative issuance fraction is 0.999 after 10 years
    ✓ Cumulative issuance fraction is 0.999999 after 20 years (78ms)
    ✓ Cumulative issuance fraction is 0.999999999 after 30 years (55ms)
    ✓ Total MSIC tokens issued is 42.20 after a minute (38ms)
    ✓ Total MSIC tokens issued is 2,531.94 after an hour (41ms)
    ✓ Total MSIC tokens issued is 60,711.40 after a day (136ms)
    ✓ Total MSIC tokens issued is 422,568.60 after a week (331ms)
    ✓ Total MSIC tokens issued is 1,772,113.21 after a month
    ✓ Total MSIC tokens issued is 5,027,363.22 after 3 months (40ms)
    ✓ Total MSIC tokens issued is 9,264,902.04 after 6 months (47ms)
    ✓ Total MSIC tokens issued is 16,000,000 after a year (47ms)
    ✓ Total MSIC tokens issued is 24,000,000 after 2 years (47ms)
    ✓ Total MSIC tokens issued is 28,000,000 after 3 years (75ms)
    ✓ Total MSIC tokens issued is 30,000,000 after 4 years (40ms)
    ✓ Total MSIC tokens issued is 31,968,750 after 10 years (69ms)
    ✓ Total MSIC tokens issued is 31,999,969.48 after 20 years (68ms)
    ✓ Total MSIC tokens issued is 31,999,999.97 after 30 years (87ms)
    - Frequent token issuance: issuance event every year, for 30 years
    - Frequent token issuance: issuance event every day, for 30 years
    - Frequent token issuance: issuance event every minute, for 1 month
    - Frequent token issuance: issuance event every minute, for 1 year

  Contract: MSICStaking revenue share tests
    ✓ stake(): reverts if amount is zero (74ms)
    ✓ REEF fee per MSIC staked increases when a redemption fee is triggered and totalStakes > 0 (1562ms)
    ✓ REEF fee per MSIC staked doesn't change when a redemption fee is triggered and totalStakes == 0 (3540ms)
    ✓ MoUSD fee per MSIC staked increases when a redemption fee is triggered and totalStakes > 0 (1757ms)
    ✓ MoUSD fee per MSIC staked doesn't change when a redemption fee is triggered and totalStakes == 0 (1705ms)
    ✓ MSIC Staking: A single staker earns all REEF and MSIC fees that occur (2143ms)
    ✓ stake(): Top-up sends out all accumulated REEF and MoUSD gains to the staker (2138ms)
    ✓ getPendingETHGain(): Returns the staker's correct pending REEF gain (1856ms)
    ✓ getPendingMoUSDGain(): Returns the staker's correct pending MoUSD gain (1965ms)
    ✓ MSIC Staking: Multiple stakers earn the correct share of all REEF and MSIC fees, based on their stake size (3133ms)
    ✓ unstake(): reverts if caller has REEF gains and can't receive REEF (1149ms)
    ✓ receive(): reverts when it receives REEF from an address that is not the Active Pool
    ✓ unstake(): reverts if user has no stake
    ✓ Test requireCallerIsTroveManager

  Contract: MoUSDToken
    Basic token functions, without Proxy
      ✓ balanceOf(): gets the balance of the account
      ✓ totalSupply(): gets the total supply
      ✓ name(): returns the token's name
      ✓ symbol(): returns the token's symbol
      ✓ decimal(): returns the number of decimal digits used
      ✓ allowance(): returns an account's spending allowance for another account's balance (77ms)
      ✓ approve(): approves an account to spend the specified amount
      ✓ approve(): reverts when spender param is address(0)
      ✓ approve(): reverts when owner param is address(0)
      ✓ transferFrom(): successfully transfers from an account which is it approved to transfer from (272ms)
      ✓ transfer(): increases the recipient's balance by the correct amount
      ✓ transfer(): reverts if amount exceeds sender's balance
      ✓ transfer(): transferring to a blacklisted address reverts (79ms)
      ✓ increaseAllowance(): increases an account's allowance by the correct amount (94ms)
      ✓ mint(): issues correct amount of tokens to the given address
      ✓ burn(): burns correct amount of tokens from the given address
      ✓ sendToPool(): changes balances of Stability pool and user by the correct amounts
      ✓ returnFromPool(): changes balances of Stability pool and user by the correct amounts (39ms)
      ✓ transfer(): transferring to a blacklisted address reverts (76ms)
      ✓ decreaseAllowance(): decreases allowance by the expected amount (38ms)
      ✓ decreaseAllowance(): fails trying to decrease more than previously allowed (39ms)
      ✓ version(): returns the token contract's version
      ✓ Initializes PERMIT_TYPEHASH correctly
      ✓ Initializes DOMAIN_SEPARATOR correctly
      ✓ Initial nonce for a given address is 0
      ✓ permits and emits an Approval event (replay protected) (69ms)
      ✓ permits(): fails with expired deadline (59ms)
      ✓ permits(): fails with the wrong signature (51ms)
    Basic token functions, with Proxy
      ✓ balanceOf(): gets the balance of the account (92ms)
      ✓ totalSupply(): gets the total supply (51ms)
      ✓ name(): returns the token's name
      ✓ symbol(): returns the token's symbol
      ✓ decimal(): returns the number of decimal digits used
      ✓ allowance(): returns an account's spending allowance for another account's balance
      ✓ approve(): approves an account to spend the specified amount
      ✓ transferFrom(): successfully transfers from an account which is it approved to transfer from (90ms)
      ✓ transfer(): increases the recipient's balance by the correct amount
      ✓ transfer(): reverts if amount exceeds sender's balance
      ✓ transfer(): transferring to a blacklisted address reverts (213ms)
      ✓ increaseAllowance(): increases an account's allowance by the correct amount (39ms)
      ✓ transfer(): transferring to a blacklisted address reverts (112ms)
      ✓ decreaseAllowance(): decreases allowance by the expected amount
      ✓ decreaseAllowance(): fails trying to decrease more than previously allowed (49ms)

  Contract: All Mosaic functions with onlyOwner modifier
    TroveManager
      ✓ setAddresses(): reverts when called by non-owner, with wrong addresses, or twice (857ms)
    BorrowerOperations
      ✓ setAddresses(): reverts when called by non-owner, with wrong addresses, or twice (765ms)
    DefaultPool
      ✓ setAddresses(): reverts when called by non-owner, with wrong addresses, or twice (154ms)
    StabilityPool
      ✓ setAddresses(): reverts when called by non-owner, with wrong addresses, or twice (441ms)
    ActivePool
      ✓ setAddresses(): reverts when called by non-owner, with wrong addresses, or twice (468ms)
    SortedTroves
      ✓ setParams(): reverts when called by non-owner, with wrong addresses, or twice (157ms)
    CommunityIssuance
      ✓ setAddresses(): reverts when called by non-owner, with wrong addresses, or twice (136ms)
    MSICStaking
      ✓ setAddresses(): reverts when called by non-owner, with wrong addresses, or twice (261ms)
    LockupContractFactory
      ✓ setMSICAddress(): reverts when called by non-owner, with wrong address, or twice (216ms)

  Contract: StabilityPool
    ✓ getETH(): gets the recorded REEF balance
    ✓ getTotalMoUSDDeposits(): gets the recorded MoUSD balance

  Contract: ActivePool
    ✓ getETH(): gets the recorded REEF balance
    ✓ getMoUSDDebt(): gets the recorded MoUSD balance
    ✓ increaseMoUSD(): increases the recorded MoUSD balance by the correct amount
    ✓ decreaseMoUSD(): decreases the recorded MoUSD balance by the correct amount
    ✓ sendETH(): decreases the recorded REEF balance by the correct amount

  Contract: DefaultPool
    ✓ getETH(): gets the recorded MoUSD balance
    ✓ getMoUSDDebt(): gets the recorded MoUSD balance
    ✓ increaseMoUSD(): increases the recorded MoUSD balance by the correct amount
    ✓ decreaseMoUSD(): decreases the recorded MoUSD balance by the correct amount (57ms)
    ✓ sendETHToActivePool(): decreases the recorded REEF balance by the correct amount (50ms)

  Contract: PriceFeed
    ✓ C1 Chainlink working: fetchPrice should return the correct price, taking into account the number of decimal digits on the aggregator (286ms)
    ✓ C1 Chainlink breaks, Tellor working: fetchPrice should return the correct Tellor price, taking into account Tellor's 6-digit granularity (2595ms)
    ✓ C1 chainlinkWorking: Chainlink broken by zero latest roundId, Tellor working: switch to usingChainlinkTellorUntrusted (87ms)
    ✓ C1 chainlinkWorking: Chainlink broken by zero latest roundId, Tellor working: use Tellor price (93ms)
    ✓ C1 chainlinkWorking: Chainlink broken by zero timestamp, Tellor working, switch to usingChainlinkTellorUntrusted (97ms)
    ✓ C1 chainlinkWorking:  Chainlink broken by zero timestamp, Tellor working, return Tellor price (97ms)
    ✓ C1 chainlinkWorking: Chainlink broken by future timestamp, Tellor working, switch to usingChainlinkTellorUntrusted (94ms)
    ✓ C1 chainlinkWorking: Chainlink broken by future timestamp, Tellor working, return Tellor price (99ms)
    ✓ C1 chainlinkWorking: Chainlink broken by negative price, Tellor working,  switch to usingChainlinkTellorUntrusted (85ms)
    ✓ C1 chainlinkWorking: Chainlink broken by negative price, Tellor working, return Tellor price (82ms)
    ✓ C1 chainlinkWorking: Chainlink broken - decimals call reverted, Tellor working, switch to usingChainlinkTellorUntrusted (117ms)
    ✓ C1 chainlinkWorking: Chainlink broken - decimals call reverted, Tellor working, return Tellor price (99ms)
    ✓ C1 chainlinkWorking: Chainlink broken - latest round call reverted, Tellor working, switch to usingChainlinkTellorUntrusted (92ms)
    ✓ C1 chainlinkWorking: latest round call reverted, Tellor working, return the Tellor price (100ms)
    ✓ C1 chainlinkWorking: previous round call reverted, Tellor working, switch to usingChainlinkTellorUntrusted (101ms)
    ✓ C1 chainlinkWorking: previous round call reverted, Tellor working, return Tellor Price (102ms)
    ✓ C1 chainlinkWorking: Chainlink frozen, Tellor working: switch to usingTellorChainlinkFrozen (112ms)
    ✓ C1 chainlinkWorking: Chainlink frozen, Tellor working: return Tellor price (123ms)
    ✓ C1 chainlinkWorking: Chainlink frozen, Tellor frozen: switch to usingTellorChainlinkFrozen (119ms)
    ✓ C1 chainlinkWorking: Chainlink frozen, Tellor frozen: return last good price (127ms)
    ✓ C1 chainlinkWorking: Chainlink times out, Tellor broken by 0 price: switch to usingChainlinkTellorUntrusted (320ms)
    ✓ C1 chainlinkWorking: Chainlink times out, Tellor broken by 0 price: return last good price (146ms)
    ✓ C1 chainlinkWorking: Chainlink is out of date by <3hrs: remain chainlinkWorking (92ms)
    ✓ C1 chainlinkWorking: Chainlink is out of date by <3hrs: return Chainklink price (132ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50%, switch to usingChainlinkTellorUntrusted (117ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50%, return the Tellor price (132ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of 50%, remain chainlinkWorking (83ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of 50%, return the Chainlink price (376ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of <50%, remain chainlinkWorking (89ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of <50%, return Chainlink price (99ms)
    ✓ C1 chainlinkWorking: Chainlink price increase of >100%, switch to usingChainlinkTellorUntrusted (473ms)
    ✓ C1 chainlinkWorking: Chainlink price increase of >100%, return Tellor price (117ms)
    ✓ C1 chainlinkWorking: Chainlink price increase of 100%, remain chainlinkWorking (82ms)
    ✓ C1 chainlinkWorking: Chainlink price increase of 100%, return Chainlink price (350ms)
    ✓ C1 chainlinkWorking: Chainlink price increase of <100%, remain chainlinkWorking (136ms)
    ✓ C1 chainlinkWorking: Chainlink price increase of <100%,  return Chainlink price (87ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor price matches: remain chainlinkWorking (154ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor price matches: return Chainlink price (135ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor price within 5% of Chainlink: remain chainlinkWorking (109ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor price within 5% of Chainlink: return Chainlink price (101ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor live but not within 5% of Chainlink: switch to usingChainlinkTellorUntrusted (116ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor live but not within 5% of Chainlink: return Tellor price (276ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor frozen: switch to usingChainlinkTellorUntrusted (145ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor frozen: return last good price (2730ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor is broken by 0 price: switch to bothOracleSuspect (68ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor is broken by 0 price: return last good price (451ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor is broken by 0 timestamp: switch to bothOracleSuspect (121ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor is broken by 0 timestamp: return last good price (87ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor is broken by future timestamp: Pricefeed switches to bothOracleSuspect (81ms)
    ✓ C1 chainlinkWorking: Chainlink price drop of >50% and Tellor is broken by future timestamp: return last good price (119ms)
    ✓ C1 chainlinkWorking: Chainlink is working and Tellor is working - remain on chainlinkWorking (77ms)
    ✓ C1 chainlinkWorking: Chainlink is working and Tellor is working - return Chainlink price (168ms)
    ✓ C1 chainlinkWorking: Chainlink is working and Tellor freezes - remain on chainlinkWorking (469ms)
    ✓ C1 chainlinkWorking: Chainlink is working and Tellor freezes - return Chainlink price (167ms)
    ✓ C1 chainlinkWorking: Chainlink is working and Tellor breaks: switch to usingChainlinkTellorUntrusted (206ms)
    ✓ C1 chainlinkWorking: Chainlink is working and Tellor breaks: return Chainlink price (105ms)
    ✓ C2 usingTellorChainlinkUntrusted: Tellor breaks by zero price: switch to bothOraclesSuspect (202ms)
    ✓ C2 usingTellorChainlinkUntrusted: Tellor breaks by zero price: return last good price (107ms)
    ✓ C2 usingTellorChainlinkUntrusted: Tellor breaks by call reverted: switch to bothOraclesSuspect (296ms)
    ✓ C2 usingTellorChainlinkUntrusted: Tellor breaks by call reverted: return last good price (112ms)
    ✓ C2 usingTellorChainlinkUntrusted: Tellor breaks by zero timestamp: switch to bothOraclesSuspect (2577ms)
    ✓ C2 usingTellorChainlinkUntrusted: Tellor breaks by zero timestamp: return last good price (82ms)
    ✓ C2 usingTellorChainlinkUntrusted: Tellor freezes - remain usingChainlinkTellorUntrusted (534ms)
    ✓ C2 usingTellorChainlinkUntrusted: Tellor freezes - return last good price (123ms)
    ✓ C2 usingTellorChainlinkUntrusted: both Tellor and Chainlink are live and <= 5% price difference - switch to chainlinkWorking (68ms)
    ✓ C2 usingTellorChainlinkUntrusted: both Tellor and Chainlink are live and <= 5% price difference - return Chainlink price (65ms)
    ✓ C2 usingTellorChainlinkUntrusted: both Tellor and Chainlink are live and > 5% price difference - remain usingChainlinkTellorUntrusted (86ms)
    ✓ C2 usingTellorChainlinkUntrusted: both Tellor and Chainlink are live and > 5% price difference - return Tellor price (569ms)
    ✓ C3 bothOraclesUntrusted: both Tellor and Chainlink are live and > 5% price difference remain bothOraclesSuspect (56ms)
    ✓ C3 bothOraclesUntrusted: both Tellor and Chainlink are live and > 5% price difference, return last good price (82ms)
    ✓ C3 bothOraclesUntrusted: both Tellor and Chainlink are live and <= 5% price difference, switch to chainlinkWorking (72ms)
    ✓ C3 bothOraclesUntrusted: both Tellor and Chainlink are live and <= 5% price difference, return Chainlink price (84ms)
    ✓ C4 usingTellorChainlinkFrozen: when both Chainlink and Tellor break, switch to bothOraclesSuspect (459ms)
    ✓ C4 usingTellorChainlinkFrozen: when both Chainlink and Tellor break, return last good price (112ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink breaks and Tellor freezes, switch to usingChainlinkTellorUntrusted (112ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink breaks and Tellor freezes, return last good price (99ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink breaks and Tellor live, switch to usingChainlinkTellorUntrusted (106ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink breaks and Tellor live, return Tellor price (102ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink is live and Tellor is live with <5% price difference, switch back to chainlinkWorking (113ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink is live and Tellor is live with <5% price difference, return Chainlink current price (138ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink is live and Tellor is live with >5% price difference, switch back to usingChainlinkTellorUntrusted (2467ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink is live and Tellor is live with >5% price difference, return Chainlink current price (85ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink is live and Tellor is live with similar price, switch back to chainlinkWorking (537ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink is live and Tellor is live with similar price, return Chainlink current price (82ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink is live and Tellor breaks, switch to usingChainlinkTellorUntrusted (187ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink is live and Tellor breaks, return Chainlink current price (81ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink still frozen and Tellor breaks, switch to usingChainlinkTellorUntrusted (176ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink still frozen and Tellor broken, return last good price (213ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink still frozen and Tellor live, remain usingTellorChainlinkFrozen (140ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink still frozen and Tellor live, return Tellor price (236ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink still frozen and Tellor freezes, remain usingTellorChainlinkFrozen (107ms)
    ✓ C4 usingTellorChainlinkFrozen: when Chainlink still frozen and Tellor freezes, return last good price (261ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live and Tellor price >5% - no status change (109ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live and Tellor price >5% - return Chainlink price (96ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live and Tellor price within <5%, switch to chainlinkWorking (171ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, Tellor price not within 5%, return Chainlink price (111ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, <50% price deviation from previous, Tellor price not within 5%, remain on usingChainlinkTellorUntrusted (161ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, <50% price deviation from previous, Tellor price not within 5%, return Chainlink price (223ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, >50% price deviation from previous, Tellor price not within 5%, remain on usingChainlinkTellorUntrusted (124ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, >50% price deviation from previous,  Tellor price not within 5%, return Chainlink price (182ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, <50% price deviation from previous, and Tellor is frozen, remain on usingChainlinkTellorUntrusted (552ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, <50% price deviation from previous, Tellor is frozen, return Chainlink price (103ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, >50% price deviation from previous, Tellor is frozen, remain on usingChainlinkTellorUntrusted (121ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink is live, >50% price deviation from previous, Tellor is frozen, return Chainlink price (105ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink frozen, remain on usingChainlinkTellorUntrusted (107ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink frozen, return last good price (531ms)
    ✓ C5 usingChainlinkTellorUntrusted: when Chainlink breaks too, switch to bothOraclesSuspect (87ms)
    ✓ C5 usingChainlinkTellorUntrusted: Chainlink breaks too, return last good price (99ms)
    PriceFeed internal testing contract
      ✓ fetchPrice before setPrice should return the default price
      ✓ should be able to fetchPrice after setPrice, output of former matching input of latter
    Mainnet PriceFeed setup
      ✓ fetchPrice should fail on contract with no chainlink address set
      ✓ fetchPrice should fail on contract with no tellor address set
      ✓ setAddresses should fail whe called by nonOwner
      ✓ setAddresses should fail after address has already been set (42ms)

  Contract: BorrowerWrappers
    ✓ proxy owner can recover REEF (85ms)
    ✓ non proxy owner cannot recover REEF
    ✓ claimCollateralAndOpenTrove(): reverts if nothing to claim (388ms)
    ✓ claimCollateralAndOpenTrove(): without sending any value (1227ms)
    ✓ claimCollateralAndOpenTrove(): sending value in the transaction (3969ms)
    ✓ claimSPRewardsAndRecycle(): only owner can call it (598ms)
    ✓ claimSPRewardsAndRecycle(): (1272ms)
    ✓ claimStakingGainsAndRecycle(): only owner can call it (1384ms)
    ✓ claimStakingGainsAndRecycle(): reverts if user has no trove (1253ms)
    ✓ claimStakingGainsAndRecycle(): with only REEF gain (1595ms)
    ✓ claimStakingGainsAndRecycle(): with only MoUSD gain (821ms)
    ✓ claimStakingGainsAndRecycle(): with both REEF and MoUSD gains (1593ms)

  Contract: SortedTroves
    SortedTroves
      ✓ contains(): returns true for addresses that have opened troves (552ms)
      ✓ contains(): returns false for addresses that have not opened troves (518ms)
      ✓ contains(): returns false for addresses that opened and then closed a trove (1009ms)
      ✓ contains(): returns true for addresses that opened, closed and then re-opened a trove (1399ms)
      ✓ contains(): returns false when there are no troves in the system
      ✓ contains(): true when list size is 1 and the trove the only one in system (208ms)
      ✓ contains(): false when list size is 1 and trove is not in the system (158ms)
      ✓ getMaxSize(): Returns the maximum list size
      ✓ Finds the correct insert position given two addresses that loosely bound the correct position (1135ms)
      - stays ordered after troves with 'infinite' ICR receive a redistribution
    SortedTroves with mock dependencies
      when params are wrongly set
        ✓ setParams(): reverts if size is zero
      when params are properly set
        ✓ insert(): fails if list is full (131ms)
        ✓ insert(): fails if list already contains the node (54ms)
        ✓ insert(): fails if id is zero
        ✓ insert(): fails if NICR is zero
        ✓ remove(): fails if id is not in the list
        ✓ reInsert(): fails if list doesn’t contain the node
        ✓ reInsert(): fails if new NICR is zero (43ms)
        ✓ findInsertPosition(): No prevId for hint - ascend list starting from nextId, result is after the tail

  Contract: StabilityPool - MSIC Rewards
    MSIC Rewards
totalMSICIssued_1: 30370113195977152000000
totalMSICIssued_2: 30370113195977152000000
      ✓ liquidation < 1 minute after a deposit does not change totalMSICIssued (743ms)
      ✓ withdrawFromSP(): reward term G does not update when no MSIC is issued (634ms)
      ✓ withdrawFromSP(): Depositors with equal initial deposit withdraw correct MSIC gain. No liquidations. No front end. (1479ms)
      ✓ withdrawFromSP(): Depositors with varying initial deposit withdraw correct MSIC gain. No liquidations. No front end. (1345ms)
      ✓ withdrawFromSP(): Depositors with varying initial deposit withdraw correct MSIC gain. No liquidations. No front end. (1925ms)
      ✓ withdrawFromSP(): Depositor withdraws correct MSIC gain after serial pool-emptying liquidations. No front-ends. (5752ms)
      ✓ MSIC issuance for a given period is not obtainable if the SP was empty during the period (551ms)
      ✓ withdrawFromSP(): Several deposits of 100 MoUSD span one scale factor change. Depositors withdraw correct MSIC gains (6075ms)
      ✓ withdrawFromSP(): Depositors with equal initial deposit withdraw correct MSIC gain. No liquidations. Front ends and kickback rates. (1660ms)
      ✓ withdrawFromSP(): Depositors with varying initial deposit withdraw correct MSIC gain. Front ends and kickback rates (2813ms)
      ✓ withdrawFromSP(): Several deposits of 10k MoUSD span one scale factor change. Depositors withdraw correct MSIC gains (4788ms)

  Contract: Pool Manager: Sum-Product rounding errors
    - Rounding errors: 100 deposits of 100MoUSD into SP, then 200 liquidations of 49MoUSD

  Contract: StabilityPool - Withdrawal of stability deposit - Reward calculations
    Stability Pool Withdrawal
      ✓ withdrawFromSP(): Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after one liquidation (757ms)
      ✓ withdrawFromSP(): Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after two identical liquidations (868ms)
      ✓ withdrawFromSP():  Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after three identical liquidations (1051ms)
      ✓ withdrawFromSP(): Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after two liquidations of increasing MoUSD (965ms)
      ✓ withdrawFromSP(): Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after three liquidations of increasing MoUSD (1152ms)
      ✓ withdrawFromSP(): Depositors with varying deposits withdraw correct compounded deposit and REEF Gain after two identical liquidations (934ms)
      ✓ withdrawFromSP(): Depositors with varying deposits withdraw correct compounded deposit and REEF Gain after three identical liquidations (1130ms)
      ✓ withdrawFromSP(): Depositors with varying deposits withdraw correct compounded deposit and REEF Gain after three varying liquidations (1193ms)

      ✓ withdrawFromSP(): A, B, C Deposit -> 2 liquidations -> D deposits -> 1 liquidation. All deposits and liquidations = 100 MoUSD.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (1512ms)
      ✓ withdrawFromSP(): A, B, C Deposit -> 2 liquidations -> D deposits -> 2 liquidations. All deposits and liquidations = 100 MoUSD.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (1637ms)
      ✓ withdrawFromSP(): A, B, C Deposit -> 2 liquidations -> D deposits -> 2 liquidations. Various deposit and liquidation vals.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (1645ms)
      ✓ withdrawFromSP(): A, B, C, D deposit -> 2 liquidations -> D withdraws -> 2 liquidations. All deposits and liquidations = 100 MoUSD.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (1704ms)
      ✓ withdrawFromSP(): A, B, C, D deposit -> 2 liquidations -> D withdraws -> 2 liquidations. Various deposit and liquidation vals. A, B, C, D withdraw correct MoUSD deposit and REEF Gain (1753ms)
      ✓ withdrawFromSP(): A, B, D deposit -> 2 liquidations -> C makes deposit -> 1 liquidation -> D withdraws -> 1 liquidation. All deposits: 100 MoUSD. Liquidations: 100,100,100,50.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (1537ms)
      ✓ withdrawFromSP(): Depositor withdraws correct compounded deposit after liquidation empties the pool (3424ms)
      ✓ withdrawFromSP(): Pool-emptying liquidation increases epoch by one, resets scaleFactor to 0, and resets P to 1e18 (1678ms)
      ✓ withdrawFromSP(): Depositors withdraw correct compounded deposit after liquidation empties the pool (1100ms)
      ✓ withdrawFromSP(): single deposit fully offset. After subsequent liquidations, depositor withdraws 0 deposit and *only* the REEF Gain from one liquidation (1049ms)
      ✓ withdrawFromSP(): Depositor withdraws correct compounded deposit after liquidation empties the pool (4540ms)
      ✓ withdrawFromSP(): deposit spans one scale factor change: Single depositor withdraws correct compounded deposit and REEF Gain after one liquidation (918ms)
      ✓ withdrawFromSP(): Several deposits of varying amounts span one scale factor change. Depositors withdraw correct compounded deposit and REEF Gain after one liquidation (1187ms)
      ✓ withdrawFromSP(): deposit spans one scale factor change: Single depositor withdraws correct compounded deposit and REEF Gain after one liquidation (778ms)
      ✓ withdrawFromSP(): Several deposits of varying amounts span one scale factor change. Depositors withdraws correct compounded deposit and REEF Gain after one liquidation (3494ms)
alice deposit: 0
      ✓ withdrawFromSP(): Deposit that decreases to less than 1e-9 of it's original value is reduced to 0 (365ms)
      ✓ withdrawFromSP(): Several deposits of 10000 MoUSD span one scale factor change. Depositors withdraws correct compounded deposit and REEF Gain after one liquidation (1676ms)
      ✓ withdrawFromSP(): 2 depositors can withdraw after each receiving half of a pool-emptying liquidation (1848ms)
      ✓ withdrawFromSP(): Depositor's REEF gain stops increasing after two scale changes (4134ms)
      ✓ withdrawFromSP(): Large liquidated coll/debt, deposits and REEF price (932ms)
      ✓ withdrawFromSP(): Small liquidated coll/debt, large deposits and REEF price (832ms)

  Contract: StabilityPool - Withdrawal of stability deposit - Reward calculations
    Stability Pool Withdrawal
      ✓ withdrawETHGainToTrove(): Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after one liquidation (1227ms)
      ✓ withdrawETHGainToTrove(): Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after two identical liquidations (1400ms)
      ✓ withdrawETHGainToTrove():  Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after three identical liquidations (1827ms)
      ✓ withdrawETHGainToTrove(): Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after two liquidations of increasing MoUSD (1597ms)
      ✓ withdrawETHGainToTrove(): Depositors with equal initial deposit withdraw correct compounded deposit and REEF Gain after three liquidations of increasing MoUSD (1711ms)
      ✓ withdrawETHGainToTrove(): Depositors with varying deposits withdraw correct compounded deposit and REEF Gain after two identical liquidations (1782ms)
      ✓ withdrawETHGainToTrove(): Depositors with varying deposits withdraw correct compounded deposit and REEF Gain after three identical liquidations (1798ms)
      ✓ withdrawETHGainToTrove(): Depositors with varying deposits withdraw correct compounded deposit and REEF Gain after three varying liquidations (4488ms)

      ✓ withdrawETHGainToTrove(): A, B, C Deposit -> 2 liquidations -> D deposits -> 1 liquidation. All deposits and liquidations = 100 MoUSD.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (2168ms)
      ✓ withdrawETHGainToTrove(): A, B, C Deposit -> 2 liquidations -> D deposits -> 2 liquidations. All deposits and liquidations = 100 MoUSD.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (5085ms)
      ✓ withdrawETHGainToTrove(): A, B, C Deposit -> 2 liquidations -> D deposits -> 2 liquidations. Various deposit and liquidation vals.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (2304ms)
      ✓ withdrawETHGainToTrove(): A, B, C, D deposit -> 2 liquidations -> D withdraws -> 2 liquidations. All deposits and liquidations = 100 MoUSD.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (2335ms)
      ✓ withdrawETHGainToTrove(): A, B, C, D deposit -> 2 liquidations -> D withdraws -> 2 liquidations. Various deposit and liquidation vals. A, B, C, D withdraw correct MoUSD deposit and REEF Gain (2145ms)
      ✓ withdrawETHGainToTrove(): A, B, D deposit -> 2 liquidations -> C makes deposit -> 1 liquidation -> D withdraws -> 1 liquidation. All deposits: 100 MoUSD. Liquidations: 100,100,100,50.  A, B, C, D withdraw correct MoUSD deposit and REEF Gain (2543ms)
      ✓ withdrawETHGainToTrove(): Depositor withdraws correct compounded deposit after liquidation empties the pool (1889ms)
      ✓ withdrawETHGainToTrove(): Pool-emptying liquidation increases epoch by one, resets scaleFactor to 0, and resets P to 1e18 (1891ms)
      ✓ withdrawETHGainToTrove(): Depositors withdraw correct compounded deposit after liquidation empties the pool (2324ms)
      ✓ withdrawETHGainToTrove(): single deposit fully offset. After subsequent liquidations, depositor withdraws 0 deposit and *only* the REEF Gain from one liquidation (1719ms)
      ✓ withdrawETHGainToTrove(): Depositor withdraws correct compounded deposit after liquidation empties the pool (3958ms)
      ✓ withdrawETHGainToTrove(): deposit spans one scale factor change: Single depositor withdraws correct compounded deposit and REEF Gain after one liquidation (1276ms)
      ✓ withdrawETHGainToTrove(): Several deposits of varying amounts span one scale factor change. Depositors withdraw correct compounded deposit and REEF Gain after one liquidation (4690ms)
      ✓ withdrawETHGainToTrove(): deposit spans one scale factor change: Single depositor withdraws correct compounded deposit and REEF Gain after one liquidation (1460ms)
      ✓ withdrawETHGainToTrove(): Several deposits of varying amounts span one scale factor change. Depositors withdraws correct compounded deposit and REEF Gain after one liquidation (1986ms)
alice deposit: 0
      ✓ withdrawETHGainToTrove(): Deposit that decreases to less than 1e-9 of it's original value is reduced to 0 (3725ms)
      ✓ withdrawETHGainToTrove(): Several deposits of 10000 MoUSD span one scale factor change. Depositors withdraws correct compounded deposit and REEF Gain after one liquidation (2361ms)
      ✓ withdrawETHGainToTrove(): 2 depositors can withdraw after each receiving half of a pool-emptying liquidation (3814ms)
      ✓ withdrawETHGainToTrove(): Large liquidated coll/debt, deposits and REEF price (959ms)
      ✓ withdrawETHGainToTrove(): Small liquidated coll/debt, large deposits and REEF price (784ms)

  Contract: StabilityPool
    Stability Pool Mechanisms
      ✓ provideToSP(): increases the Stability Pool MoUSD balance (354ms)
      ✓ provideToSP(): updates the user's deposit record in StabilityPool (355ms)
      ✓ provideToSP(): reduces the user's MoUSD balance by the correct amount (321ms)
      ✓ provideToSP(): increases totalMoUSDDeposits by correct amount (283ms)
      ✓ provideToSP(): Correctly updates user snapshots of accumulated rewards per unit staked (4003ms)
      ✓ provideToSP(), multiple deposits: updates user's deposit and snapshots (2543ms)
      ✓ provideToSP(): reverts if user tries to provide more than their MoUSD balance (1030ms)
      ✓ provideToSP(): reverts if user tries to provide 2^256-1 MoUSD, which exceeds their balance (508ms)
      ✓ provideToSP(): reverts if cannot receive REEF Gain (1073ms)
      ✓ provideToSP(): doesn't impact other users' deposits or REEF gains (1906ms)
      ✓ provideToSP(): doesn't impact system debt, collateral or TCR (2287ms)
      ✓ provideToSP(): doesn't impact any troves, including the caller's trove (1810ms)
      ✓ provideToSP(): doesn't protect the depositor's trove from liquidation (1082ms)
      ✓ provideToSP(): providing 0 MoUSD reverts (1091ms)
      ✓ provideToSP(), new deposit: when SP > 0, triggers MSIC reward event - increases the sum G (1072ms)
      ✓ provideToSP(), new deposit: when SP is empty, doesn't update G (4734ms)
      ✓ provideToSP(), new deposit: sets the correct front end tag (1128ms)
      ✓ provideToSP(), new deposit: depositor does not receive any MSIC rewards (671ms)
      ✓ provideToSP(), new deposit after past full withdrawal: depositor does not receive any MSIC rewards (1679ms)
      ✓ provideToSP(), new eligible deposit: tagged front end receives MSIC rewards (1605ms)
      ✓ provideToSP(), new eligible deposit: tagged front end's stake increases (848ms)
      ✓ provideToSP(), new eligible deposit: tagged front end's snapshots update (1913ms)
      ✓ provideToSP(), new deposit: depositor does not receive REEF gains (957ms)
      ✓ provideToSP(), new deposit after past full withdrawal: depositor does not receive REEF gains (1928ms)
      ✓ provideToSP(), topup: triggers MSIC reward event - increases the sum G (1007ms)
      ✓ provideToSP(), topup from different front end: doesn't change the front end tag (1511ms)
      ✓ provideToSP(), topup: depositor receives MSIC rewards (1487ms)
      ✓ provideToSP(), topup: tagged front end receives MSIC rewards (1036ms)
      ✓ provideToSP(), topup: tagged front end's stake increases (1816ms)
      ✓ provideToSP(), topup: tagged front end's snapshots update (1816ms)
      ✓ provideToSP(): reverts when amount is zero (686ms)
      ✓ provideToSP(): reverts if user is a registered front end (802ms)
      ✓ provideToSP(): reverts if provided tag is not a registered front end (587ms)
      ✓ withdrawFromSP(): reverts when user has no active deposit (597ms)
      ✓ withdrawFromSP(): reverts when amount > 0 and system has an undercollateralized trove (453ms)
      ✓ withdrawFromSP(): partial retrieval - retrieves correct MoUSD amount and the entire REEF Gain, and updates deposit (1102ms)
      ✓ withdrawFromSP(): partial retrieval - leaves the correct amount of MoUSD in the Stability Pool (1128ms)
      ✓ withdrawFromSP(): full retrieval - leaves the correct amount of MoUSD in the Stability Pool (1091ms)
      ✓ withdrawFromSP(): Subsequent deposit and withdrawal attempt from same account, with no intermediate liquidations, withdraws zero REEF (1494ms)
      ✓ withdrawFromSP(): it correctly updates the user's MoUSD and REEF snapshots of entitled reward per unit staked (1049ms)
      ✓ withdrawFromSP(): decreases StabilityPool REEF (3952ms)
      ✓ withdrawFromSP(): All depositors are able to withdraw from the SP to their account (2393ms)
      ✓ withdrawFromSP(): increases depositor's MoUSD token balance by the expected amount (2098ms)
      ✓ withdrawFromSP(): doesn't impact other users Stability deposits or REEF gains (4954ms)
      ✓ withdrawFromSP(): doesn't impact system debt, collateral or TCR  (1500ms)
      ✓ withdrawFromSP(): doesn't impact any troves, including the caller's trove (1085ms)
      ✓ withdrawFromSP(): succeeds when amount is 0 and system has an undercollateralized trove (933ms)
      ✓ withdrawFromSP(): withdrawing 0 MoUSD doesn't alter the caller's deposit or the total MoUSD in the Stability Pool (993ms)
      ✓ withdrawFromSP(): withdrawing 0 REEF Gain does not alter the caller's REEF balance, their trove collateral, or the REEF  in the Stability Pool (1139ms)
      ✓ withdrawFromSP(): Request to withdraw > caller's deposit only withdraws the caller's compounded deposit (1260ms)
      ✓ withdrawFromSP(): Request to withdraw 2^256-1 MoUSD only withdraws the caller's compounded deposit (1229ms)
      ✓ withdrawFromSP(): caller can withdraw full deposit and REEF gain during Recovery Mode (4371ms)
      ✓ getDepositorETHGain(): depositor does not earn further REEF gains from liquidations while their compounded deposit == 0:  (1831ms)
      ✓ withdrawFromSP(): triggers MSIC reward event - increases the sum G (982ms)
      ✓ withdrawFromSP(), partial withdrawal: doesn't change the front end tag (1421ms)
      ✓ withdrawFromSP(), partial withdrawal: depositor receives MSIC rewards (1155ms)
      ✓ withdrawFromSP(), partial withdrawal: tagged front end receives MSIC rewards (1245ms)
      ✓ withdrawFromSP(), partial withdrawal: tagged front end's stake decreases (1803ms)
      ✓ withdrawFromSP(), partial withdrawal: tagged front end's snapshots update (1713ms)
      ✓ withdrawFromSP(), full withdrawal: removes deposit's front end tag (970ms)
      ✓ withdrawFromSP(), full withdrawal: zero's depositor's snapshots (1434ms)
      ✓ withdrawFromSP(), full withdrawal that reduces front end stake to 0: zero’s the front end’s snapshots (1248ms)
      ✓ withdrawFromSP(), reverts when initial deposit value is 0 (1037ms)
      ✓ withdrawETHGainToTrove(): reverts when user has no active deposit (1043ms)
      ✓ withdrawETHGainToTrove(): Applies MoUSDLoss to user's deposit, and redirects REEF reward to user's Trove (932ms)
      ✓ withdrawETHGainToTrove(): reverts if it would leave trove with ICR < MCR (3920ms)
      ✓ withdrawETHGainToTrove(): Subsequent deposit and withdrawal attempt from same account, with no intermediate liquidations, withdraws zero REEF (976ms)
      ✓ withdrawETHGainToTrove(): decreases StabilityPool REEF and increases activePool REEF (976ms)
      ✓ withdrawETHGainToTrove(): All depositors are able to withdraw their REEF gain from the SP to their Trove (5974ms)
      ✓ withdrawETHGainToTrove(): All depositors withdraw, each withdraw their correct REEF gain (2591ms)
      ✓ withdrawETHGainToTrove(): caller can withdraw full deposit and REEF gain to their trove during Recovery Mode (1629ms)
      ✓ withdrawETHGainToTrove(): reverts if user has no trove (967ms)
      ✓ withdrawETHGainToTrove(): triggers MSIC reward event - increases the sum G (1298ms)
      ✓ withdrawETHGainToTrove(), partial withdrawal: doesn't change the front end tag (4778ms)
      ✓ withdrawETHGainToTrove(), eligible deposit: depositor receives MSIC rewards (1607ms)
      ✓ withdrawETHGainToTrove(), eligible deposit: tagged front end receives MSIC rewards (1701ms)
      ✓ withdrawETHGainToTrove(), eligible deposit: tagged front end's stake decreases (5345ms)
      ✓ withdrawETHGainToTrove(), eligible deposit: tagged front end's snapshots update (1984ms)
      ✓ withdrawETHGainToTrove(): reverts when depositor has no REEF gain (1172ms)
      ✓ registerFrontEnd(): registers the front end and chosen kickback rate (173ms)
      ✓ registerFrontEnd(): reverts if the front end is already registered (196ms)
      ✓ registerFrontEnd(): reverts if the kickback rate >1 (57ms)
      ✓ registerFrontEnd(): reverts if address has a non-zero deposit already (702ms)

  Contract: TroveManager
totalStakesSnapshot after L1: 200000002000000000000000000000
totalCollateralSnapshot after L1: 399000002000000000000000000000
Snapshots ratio after L1: 501253135332064484
B pending REEF reward after L1: 39799999602000003960000000000
B stake after L1: 40000000000000000000000000000
B stake after A1: 39999999999999999989974957243
Snapshots ratio after A1: 501253135332064484
B stake after L2: 39999999999999999989974957243
Snapshots ratio after L2: 501253134833317619
B stake after A2: 39999999999999999983267686056
B stake after L3: 39999999999999999983267686056
Snapshots ratio after L3: 501253134334570755
B stake after A3: 39999999999999999978023472178
B stake after L4: 39999999999999999978023472178
Snapshots ratio after L4: 501253133835823890
B stake after A4: 39999999999999999993921497875
B stake after L5: 39999999999999999993921497875
Snapshots ratio after L5: 501253133337077025
B stake after A5: 39999999999999999994797348633
B stake after L6: 39999999999999999994797348633
Snapshots ratio after L6: 501253132838330161
B stake after A6: 39999999999999999993468266716
B stake after L7: 39999999999999999993468266716
Snapshots ratio after L7: 501253132339583296
B stake after A7: 39999999999999999992497700314
B stake after L8: 39999999999999999992497700314
Snapshots ratio after L8: 501253131840836431
B stake after A8: 39999999999999999992398338824
B stake after L9: 39999999999999999992398338824
Snapshots ratio after L9: 501253131342089567
B stake after A9: 39999999999999999993272719884
B stake after L10: 39999999999999999993272719884
Snapshots ratio after L10: 501253130843342702
B stake after A10: 39999999999999999995141350785
B stake after L11: 39999999999999999995141350785
Snapshots ratio after L11: 501253130344595837
B stake after A11: 39999999999999999998008332745
    ✓ A given trove's stake decline is negligible with adjustments and tiny liquidations (4988ms)

  Contract: TroveManager - Redistribution reward calculations
    ✓ redistribution: A, B Open. B Liquidated. C, D Open. D Liquidated. Distributes correct rewards (1514ms)
    ✓ redistribution: A, B, C Open. C Liquidated. D, E, F Open. F Liquidated. Distributes correct rewards (1537ms)
    ✓ redistribution: Sequence of alternate opening/liquidation: final surviving trove has REEF from all previously liquidated troves (1667ms)
    ✓ redistribution: A,B,C,D,E open. Liq(A). B adds coll. Liq(C). B and D have correct coll and debt (1915ms)
    ✓ redistribution: A,B,C,D open. Liq(A). B adds coll. Liq(C). B and D have correct coll and debt (1962ms)
    ✓ redistribution: A,B,C Open. Liq(C). B adds coll. Liq(A). B acquires all coll and debt (1102ms)
    ✓ redistribution: A,B,C Open. Liq(C). B tops up coll. D Opens. Liq(D). Distributes correct rewards. (1133ms)
    ✓ 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 (1217ms)
    ✓ 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 (1627ms)
    ✓ redistribution: A,B,C Open. Liq(C). B withdraws coll. Liq(A). B acquires all coll and debt (1062ms)
    ✓ redistribution: A,B,C Open. Liq(C). B withdraws coll. D Opens. Liq(D). Distributes correct rewards. (1050ms)
    ✓ 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 (1254ms)
    ✓ 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 (2218ms)
    ✓ 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 (1990ms)
    ✓ 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 (2513ms)

  Contract: TroveManager - in Recovery Mode
    ✓ checkRecoveryMode(): Returns true if TCR falls below CCR (555ms)
    ✓ checkRecoveryMode(): Returns true if TCR stays less than CCR (783ms)
    ✓ checkRecoveryMode(): returns false if TCR stays above CCR (775ms)
    ✓ checkRecoveryMode(): returns false if TCR rises above CCR (517ms)
    ✓ liquidate(), with ICR < 100%: removes stake and updates totalStakes (958ms)
    ✓ liquidate(), with ICR < 100%: updates system snapshots correctly (1181ms)
    ✓ liquidate(), with ICR < 100%: closes the Trove and removes it from the Trove array (808ms)
    ✓ liquidate(), with ICR < 100%: only redistributes to active Troves - no offset to Stability Pool (1527ms)
    ✓ liquidate(), with 100 < ICR < 110%: removes stake and updates totalStakes (969ms)
    ✓ liquidate(), with 100% < ICR < 110%: updates system snapshots correctly (1292ms)
    ✓ liquidate(), with 100% < ICR < 110%: closes the Trove and removes it from the Trove array (965ms)
    ✓ liquidate(), with 100% < ICR < 110%: offsets as much debt as possible with the Stability Pool, then redistributes the remainder coll and debt (1034ms)
    ✓ liquidate(), with ICR > 110%, trove has lowest ICR, and StabilityPool is empty: does nothing (1245ms)
    ✓ liquidate(), with 110% < ICR < TCR, and StabilityPool MoUSD > debt to liquidate: offsets the trove entirely with the pool (1265ms)
    ✓ liquidate(), with ICR% = 110 < TCR, and StabilityPool MoUSD > debt to liquidate: offsets the trove entirely with the pool, there’s no collateral surplus (1382ms)
    ✓ liquidate(), with  110% < ICR < TCR, and StabilityPool MoUSD > debt to liquidate: removes stake and updates totalStakes (1361ms)
    ✓ liquidate(), with  110% < ICR < TCR, and StabilityPool MoUSD > debt to liquidate: updates system snapshots (1287ms)
    ✓ liquidate(), with 110% < ICR < TCR, and StabilityPool MoUSD > debt to liquidate: closes the Trove (6532ms)
    ✓ liquidate(), with 110% < ICR < TCR, and StabilityPool MoUSD > debt to liquidate: can liquidate troves out of order (2667ms)
    ✓ liquidate(), with ICR > 110%, and StabilityPool MoUSD < liquidated debt: Trove remains active (985ms)
    ✓ liquidate(), with ICR > 110%, and StabilityPool MoUSD < liquidated debt: Trove remains in TroveOwners array (1134ms)
    ✓ liquidate(), with ICR > 110%, and StabilityPool MoUSD < liquidated debt: nothing happens (1146ms)
    ✓ liquidate(), with ICR > 110%, and StabilityPool MoUSD < liquidated debt: updates system shapshots (1284ms)
    ✓ liquidate(), with ICR > 110%, and StabilityPool MoUSD < liquidated debt: causes correct Pool offset and REEF gain, and doesn't redistribute to active troves (1266ms)
    ✓ liquidate(), with ICR > 110%, and StabilityPool MoUSD < liquidated debt: ICR of non liquidated trove does not change (2161ms)
    ✓ liquidate() with ICR > 110%, and StabilityPool MoUSD < liquidated debt: total liquidated coll and debt is correct (1912ms)
    ✓ liquidate(): Doesn't liquidate undercollateralized trove if it is the only trove in the system (652ms)
    ✓ liquidate(): Liquidates undercollateralized trove if there are two troves in the system (997ms)
    ✓ liquidate(): does nothing if trove has >= 110% ICR and the Stability Pool is empty (1019ms)
    ✓ liquidate(): does nothing if trove ICR >= TCR, and SP covers trove's debt (1391ms)
    ✓ liquidate(): reverts if trove is non-existent (815ms)
    ✓ liquidate(): reverts if trove has been closed (1044ms)
    ✓ liquidate(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt (1878ms)
    ✓ liquidate(): does not affect the SP deposit or REEF gain when called on an SP depositor's address that has no trove (708ms)
    ✓ liquidate(): does not alter the liquidated user's token balance (1312ms)
    ✓ liquidate(), with 110% < ICR < TCR, can claim collateral, re-open, be reedemed and claim again (2055ms)
    ✓ liquidate(), with 110% < ICR < TCR, can claim collateral, after another claim from a redemption (2300ms)
    ✓ liquidateTroves(): With all ICRs > 110%, Liquidates Troves until system leaves recovery mode (3129ms)
    ✓ liquidateTroves(): Liquidates Troves until 1) system has left recovery mode AND 2) it reaches a Trove with ICR >= 110% (2467ms)
    ✓ liquidateTroves(): liquidates only up to the requested number of undercollateralized troves (7021ms)
    ✓ liquidateTroves(): does nothing if n = 0 (952ms)
    ✓ liquidateTroves(): closes every Trove with ICR < MCR, when n > number of undercollateralized troves (2065ms)
    ✓ liquidateTroves(): a liquidation sequence containing Pool offsets increases the TCR (2024ms)
    ✓ liquidateTroves(): A liquidation sequence of pure redistributions decreases the TCR, due to gas compensation, but up to 0.5% (6805ms)
    ✓ liquidateTroves(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt (945ms)
    ✓ liquidateTroves(): does nothing if all troves have ICR > 110% and Stability Pool is empty (692ms)
    ✓ liquidateTroves(): emits liquidation event with correct values when all troves have ICR > 110% and Stability Pool covers a subset of troves (1300ms)
    ✓ liquidateTroves():  emits liquidation event with correct values when all troves have ICR > 110% and Stability Pool covers a subset of troves, including a partial (1362ms)
    ✓ liquidateTroves(): does not affect the liquidated user's token balances (4805ms)
    ✓ liquidateTroves(): Liquidating troves at 100 < ICR < 110 with SP deposits correctly impacts their SP deposit and REEF gain (1556ms)
    ✓ liquidateTroves(): Liquidating troves at ICR <=100% with SP deposits does not alter their deposit or REEF gain (1391ms)
    ✓ liquidateTroves() with a non fullfilled liquidation: non liquidated trove remains active (1140ms)
    ✓ liquidateTroves() with a non fullfilled liquidation: non liquidated trove remains in TroveOwners Array (1378ms)
gasUsed:  609826
true
    ✓ liquidateTroves() with a non fullfilled liquidation: still can liquidate further troves after the non-liquidated, emptied pool (4864ms)
gasUsed:  609826
    ✓ liquidateTroves() with a non fullfilled liquidation: still can liquidate further troves after the non-liquidated, non emptied pool (1286ms)
    ✓ liquidateTroves() with a non fullfilled liquidation: total liquidated coll and debt is correct (1175ms)
    ✓ liquidateTroves() with a non fullfilled liquidation: emits correct liquidation event values (1364ms)
    ✓ liquidateTroves() with a non fullfilled liquidation: ICR of non liquidated trove does not change (1387ms)
    ✓ batchLiquidateTroves(): Liquidates all troves with ICR < 110%, transitioning Normal -> Recovery Mode (4957ms)
    ✓ batchLiquidateTroves(): Liquidates all troves with ICR < 110%, transitioning Recovery -> Normal Mode (1492ms)
    ✓ batchLiquidateTroves(): Liquidates all troves with ICR < 110%, transitioning Normal -> Recovery Mode (1922ms)
    ✓ batchLiquidateTroves() with a non fullfilled liquidation: non liquidated trove remains active (1286ms)
    ✓ batchLiquidateTroves() with a non fullfilled liquidation: non liquidated trove remains in Trove Owners array (1555ms)
gasUsed:  636956
    ✓ batchLiquidateTroves() with a non fullfilled liquidation: still can liquidate further troves after the non-liquidated, emptied pool (1465ms)
gasUsed:  636956
    ✓ batchLiquidateTroves() with a non fullfilled liquidation: still can liquidate further troves after the non-liquidated, non emptied pool (1521ms)
    ✓ batchLiquidateTroves() with a non fullfilled liquidation: total liquidated coll and debt is correct (1320ms)
    ✓ batchLiquidateTroves() with a non fullfilled liquidation: emits correct liquidation event values (1238ms)
    ✓ batchLiquidateTroves() with a non fullfilled liquidation: ICR of non liquidated trove does not change (1416ms)
    ✓ batchLiquidateTroves(), with 110% < ICR < TCR, and StabilityPool MoUSD > debt to liquidate: can liquidate troves out of order (1357ms)
    ✓ batchLiquidateTroves(), with 110% < ICR < TCR, and StabilityPool empty: doesn't liquidate any troves (1161ms)
    ✓ batchLiquidateTroves(): skips liquidation of troves with ICR > TCR, regardless of Stability Pool size (2686ms)
    ✓ batchLiquidateTroves(): emits liquidation event with correct values when all troves have ICR > 110% and Stability Pool covers a subset of troves (1530ms)
    ✓ batchLiquidateTroves(): emits liquidation event with correct values when all troves have ICR > 110% and Stability Pool covers a subset of troves, including a partial (4965ms)

  Contract: TroveManager
    ✓ liquidate(): closes a Trove that has ICR < MCR (573ms)
    ✓ liquidate(): decreases ActivePool REEF and MoUSDDebt by correct amounts (567ms)
    ✓ liquidate(): increases DefaultPool REEF and MoUSD debt by correct amounts (553ms)
    ✓ liquidate(): removes the Trove's stake from the total stakes (608ms)
    ✓ liquidate(): Removes the correct trove from the TroveOwners array, and moves the last array element to the new empty slot (1276ms)
    ✓ liquidate(): updates the snapshots of total stakes and total collateral (422ms)
    ✓ liquidate(): updates the L_ETH and L_MoUSDDebt reward-per-unit-staked totals (984ms)
    ✓ liquidate(): Liquidates undercollateralized trove if there are two troves in the system (503ms)
    ✓ liquidate(): reverts if trove is non-existent (303ms)
    ✓ liquidate(): reverts if trove has been closed (745ms)
    ✓ liquidate(): does nothing if trove has >= 110% ICR (597ms)
    ✓ 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 (2590ms)
    ✓ liquidate(): Pool offsets increase the TCR (6140ms)
    ✓ liquidate(): a pure redistribution reduces the TCR only as a result of compensation (2570ms)
    ✓ liquidate(): does not affect the SP deposit or REEF gain when called on an SP depositor's address that has no trove (964ms)
    ✓ liquidate(): does not liquidate a SP depositor's trove with ICR > 110%, and does not affect their SP deposit or REEF gain (892ms)
    ✓ liquidate(): liquidates a SP depositor's trove with ICR < 110%, and the liquidation correctly impacts their SP deposit and REEF gain (1141ms)
    ✓ liquidate(): does not alter the liquidated user's token balance (1104ms)
    ✓ liquidate(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt (1573ms)
    ✓ liquidate(): when SP > 0, triggers MSIC reward event - increases the sum G (1081ms)
    ✓ liquidate(): when SP is empty, doesn't update G (1127ms)
    ✓ liquidateTroves(): liquidates a Trove that a) was skipped in a previous liquidation and b) has pending rewards (5574ms)
    ✓ liquidateTroves(): closes every Trove with ICR < MCR, when n > number of undercollateralized troves (2003ms)
    ✓ liquidateTroves(): liquidates  up to the requested number of undercollateralized troves (1230ms)
    ✓ liquidateTroves(): does nothing if all troves have ICR > 110% (1021ms)
    ✓ liquidateTroves(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt (1246ms)
    ✓ liquidateTroves(): reverts if n = 0 (764ms)
    ✓ liquidateTroves():  liquidates troves with ICR < MCR (1751ms)
    ✓ liquidateTroves(): does not affect the liquidated user's token balances (999ms)
    ✓ liquidateTroves(): A liquidation sequence containing Pool offsets increases the TCR (6204ms)
    ✓ liquidateTroves(): A liquidation sequence of pure redistributions decreases the TCR, due to gas compensation, but up to 0.5% (1929ms)
    ✓ liquidateTroves(): Liquidating troves with SP deposits correctly impacts their SP deposit and REEF gain (1214ms)
    ✓ liquidateTroves(): when SP > 0, triggers MSIC reward event - increases the sum G (5057ms)
    ✓ liquidateTroves(): when SP is empty, doesn't update G (1722ms)
    ✓ batchLiquidateTroves(): liquidates a Trove that a) was skipped in a previous liquidation and b) has pending rewards (1912ms)
    ✓ batchLiquidateTroves(): closes every trove with ICR < MCR in the given array (1351ms)
    ✓ batchLiquidateTroves(): does not liquidate troves that are not in the given array (5228ms)
    ✓ batchLiquidateTroves(): does not close troves with ICR >= MCR in the given array (1442ms)
    ✓ batchLiquidateTroves(): reverts if array is empty (978ms)
    ✓ batchLiquidateTroves(): skips if trove is non-existent (1295ms)
    ✓ batchLiquidateTroves(): skips if a trove has been closed (5183ms)
    ✓ batchLiquidateTroves: when SP > 0, triggers MSIC reward event - increases the sum G (1428ms)
    ✓ batchLiquidateTroves(): when SP is empty, doesn't update G (1655ms)
    ✓ getRedemptionHints(): gets the address of the first Trove and the final ICR of the last Trove involved in a redemption (621ms)
    ✓ getRedemptionHints(): returns 0 as partialRedemptionHintNICR when reaching _maxIterations (715ms)
    ✓ redeemCollateral(): cancels the provided MoUSD with debt from Troves with the lowest ICRs and sends an equivalent amount of Ether (838ms)
    ✓ redeemCollateral(): with invalid first hint, zero address (991ms)
    ✓ redeemCollateral(): with invalid first hint, non-existent trove (1003ms)
    ✓ redeemCollateral(): with invalid first hint, trove below MCR (1392ms)
    ✓ redeemCollateral(): ends the redemption sequence when the token redemption request has been filled (1583ms)
    ✓ redeemCollateral(): ends the redemption sequence when max iterations have been reached (1038ms)
    ✓ redeemCollateral(): performs partial redemption if resultant debt is > minimum net debt (1411ms)
    ✓ redeemCollateral(): doesn't perform partial redemption if resultant debt would be < minimum net debt (1487ms)
    ✓ redeemCollateral(): doesnt perform the final partial redemption in the sequence if the hint is out-of-date (1583ms)
    - redeemCollateral(): can redeem if there is zero active debt but non-zero debt in DefaultPool
    ✓ redeemCollateral(): doesn't touch Troves with ICR < 110% (4743ms)
    ✓ redeemCollateral(): finds the last Trove with ICR == 110% even if there is more than one (1124ms)
    ✓ redeemCollateral(): reverts when TCR < MCR (1238ms)
    ✓ redeemCollateral(): reverts when argument _amount is 0 (1038ms)
    ✓ redeemCollateral(): reverts if max fee > 100% (1918ms)
    ✓ redeemCollateral(): reverts if max fee < 0.5% (2011ms)
    ✓ redeemCollateral(): reverts if fee exceeds max fee percentage (2899ms)
    ✓ redeemCollateral(): succeeds if fee is less than max fee percentage (3127ms)
    ✓ redeemCollateral(): doesn't affect the Stability Pool deposits or REEF gain of redeemed-from troves (2311ms)
    ✓ redeemCollateral(): caller can redeem their entire MoUSDToken balance (1086ms)
    ✓ redeemCollateral(): reverts when requested redemption amount exceeds caller's MoUSD token balance (1320ms)
    ✓ redeemCollateral(): value of issued REEF == face value of redeemed MoUSD (assuming 1 MoUSD has value of $1) (1353ms)
    ✓ redeemCollateral(): reverts if there is zero outstanding system debt (66ms)
    ✓ redeemCollateral(): reverts if caller's tries to redeem more than the outstanding system debt (367ms)
    ✓ redeemCollateral(): a redemption made when base rate is zero increases the base rate (1187ms)
    ✓ redeemCollateral(): a redemption made when base rate is non-zero increases the base rate, for negligible time passed (1987ms)
    ✓ redeemCollateral(): lastFeeOpTime doesn't update if less time than decay interval has passed since the last fee operation [ @skip-on-coverage ] (2515ms)
    ✓ redeemCollateral(): a redemption made at zero base rate send a non-zero ETHFee to MSIC staking contract (5136ms)
    ✓ redeemCollateral(): a redemption made at zero base increases the REEF-fees-per-MSIC-staked in MSIC Staking contract (1207ms)
    ✓ redeemCollateral(): a redemption made at a non-zero base rate send a non-zero ETHFee to MSIC staking contract (1730ms)
    ✓ redeemCollateral(): a redemption made at a non-zero base rate increases REEF-per-MSIC-staked in the staking contract (5971ms)
    ✓ redeemCollateral(): a redemption sends the REEF remainder (ETHDrawn - ETHFee) to the redeemer (1113ms)
    ✓ redeemCollateral(): a full redemption (leaving trove with 0 debt), closes the trove (1553ms)
    ✓ redeemCollateral(): emits correct debt and coll values in each redeemed trove's TroveUpdated event (1416ms)
    ✓ redeemCollateral(): a redemption that closes a trove leaves the trove's REEF surplus (collateral - REEF drawn) available for the trove owner to claim (5373ms)
    ✓ redeemCollateral(): a redemption that closes a trove leaves the trove's REEF surplus (collateral - REEF drawn) available for the trove owner after re-opening trove (2154ms)
    ✓ redeemCollateral(): reverts if fee eats up all returned collateral (1412ms)
    ✓ getPendingMoUSDDebtReward(): Returns 0 if there is no pending MoUSDDebt reward (618ms)
    ✓ getPendingETHReward(): Returns 0 if there is no pending REEF reward (620ms)
    ✓ computeICR(): Returns 0 if trove's coll is worth 0
    ✓ computeICR(): Returns 2^256-1 for REEF:USD = 100, coll = 1 REEF, debt = 100 MoUSD
    ✓ computeICR(): returns correct ICR for REEF:USD = 100, coll = 200 REEF, debt = 30 MoUSD
    ✓ computeICR(): returns correct ICR for REEF:USD = 250, coll = 1350 REEF, debt = 127 MoUSD
    ✓ computeICR(): returns correct ICR for REEF:USD = 100, coll = 1 REEF, debt = 54321 MoUSD
    ✓ computeICR(): Returns 2^256-1 if trove has non-zero coll and zero debt
    ✓ checkRecoveryMode(): Returns true when TCR < 150% (351ms)
    ✓ checkRecoveryMode(): Returns false when TCR == 150% (366ms)
    ✓ checkRecoveryMode(): Returns false when TCR > 150% (365ms)
    ✓ checkRecoveryMode(): Returns false when TCR == 0 (604ms)
    ✓ getTroveStake(): Returns stake (511ms)
    ✓ getTroveColl(): Returns coll (494ms)
    ✓ getTroveDebt(): Returns debt (400ms)
    ✓ getTroveStatus(): Returns status (434ms)
    ✓ hasPendingRewards(): Returns false it trove is not active

  Contract: Unipool
    Unipool
      ✓ Two stakers with the same stakes wait DURATION (112ms)
      ✓ Two stakers with the different (1:3) stakes wait DURATION (206ms)
      ✓ Two stakers with the different (1:3) stakes wait DURATION and DURATION/2 (93ms)
      ✓ Three stakers with the different (1:3:5) stakes wait different durations (392ms)
      ✓ Four stakers with gaps of zero total supply (516ms)
      ✓ Four stakers with gaps of zero total supply, with claims in between (430ms)
    Unipool, before calling setAddresses
      ✓ Stake fails
      ✓ Withdraw falis
      ✓ Claim fails
      ✓ Exit fails


  1019 passing (29m)
  8 pending

Done in 1740.19s.

Last updated