diff --git a/core/simulations/configs/specificBlockFork.ts b/core/simulations/configs/specificBlockFork.ts index 6e9fa375f..c669ae9af 100644 --- a/core/simulations/configs/specificBlockFork.ts +++ b/core/simulations/configs/specificBlockFork.ts @@ -1,3 +1,4 @@ +import { addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat/balance'; import { warpTime, resetNetworkAndSetupWallet } from '../../helpers/hardhat/network'; import promptToGetBlockNumber from '../helpers/promptToGetBlockNumber'; import { Simulation } from '../types'; @@ -12,6 +13,13 @@ const simulation: Simulation = { await resetNetworkAndSetupWallet(selectedBlockNumber); }, }, + { + title: 'Add DAI and MKR to the wallet', + entry: async () => { + await addDaiToBalance(); + await addMkrToBalance(); + }, + }, { title: 'Skip time', entry: async () => { diff --git a/core/src/bignumber.ts b/core/src/bignumber.ts index c6ff8916c..9df451e7a 100644 --- a/core/src/bignumber.ts +++ b/core/src/bignumber.ts @@ -1,6 +1,6 @@ import BigNumber from 'bignumber.js'; -import { RAY_NUMBER_OF_DIGITS } from './constants/UNITS'; +import { RAD_NUMBER_OF_DIGITS } from './constants/UNITS'; -BigNumber.config({ DECIMAL_PLACES: RAY_NUMBER_OF_DIGITS }); +BigNumber.config({ DECIMAL_PLACES: RAD_NUMBER_OF_DIGITS }); export default BigNumber; diff --git a/core/src/helpers/parseMetamaskError.ts b/core/src/helpers/parseMetamaskError.ts index 8fffcea94..406bbdde9 100644 --- a/core/src/helpers/parseMetamaskError.ts +++ b/core/src/helpers/parseMetamaskError.ts @@ -29,7 +29,19 @@ const getErrorTitle = function (errorMessage = '') { return errorMessage.substring(0, jsonStartIndex).trim(); }; +const getVMError = function (errorMessage = '') { + const prefix = 'Error: VM Exception while processing transaction:'; + if (!errorMessage.startsWith(prefix)) { + return ''; + } + return errorMessage.replace(prefix, 'VM').trim(); +}; + const parseMetamaskError = function (errorMessage = ''): unknown { + const vmError = getVMError(errorMessage); + if (vmError) { + return vmError; + } const errorTitle = getErrorTitle(errorMessage); if (!errorTitle) { return truncateText(errorMessage || UNKNOWN_ERROR_TEXT); diff --git a/core/src/price.ts b/core/src/price.ts index b960e9e70..2a8fef7b4 100644 --- a/core/src/price.ts +++ b/core/src/price.ts @@ -1,6 +1,7 @@ import type { Auction } from './types'; import BigNumber from './bignumber'; import { addSeconds } from 'date-fns'; +import { RAD_NUMBER_OF_DIGITS } from './constants/UNITS'; const checkAuctionStartDate = function (startDate: Date, currentDate: Date): void { const auctionStartTimestamp = startDate.getTime(); @@ -65,16 +66,15 @@ export const calculateTransactionCollateralOutcome = function ( const collateralToBuyForTheBid = bidAmountDai.dividedBy(unitPrice); const potentialOutcomeCollateralAmount = BigNumber.minimum(collateralToBuyForTheBid, auction.collateralAmount); // slice const potentialOutcomeTotalPrice = potentialOutcomeCollateralAmount.multipliedBy(unitPrice); // owe - const approximateDebt = new BigNumber(auction.debtDAI.toPrecision(16, BigNumber.ROUND_DOWN)); - const approximatePotentialOutcomeTotalPrice = new BigNumber( - potentialOutcomeTotalPrice.toPrecision(16, BigNumber.ROUND_DOWN) + const potentialOutcomeTotalPriceRounded = new BigNumber( // rounded up to match debtDAI precision + potentialOutcomeTotalPrice.toPrecision(RAD_NUMBER_OF_DIGITS, BigNumber.ROUND_UP) ); if ( // if owe > tab - // soft compensation because of precision problems. - approximateDebt.isLessThan(approximatePotentialOutcomeTotalPrice) + potentialOutcomeTotalPriceRounded.isGreaterThan(auction.debtDAI) ) { - return auction.debtDAI.dividedBy(unitPrice); // return tab / price + // return tab / price + 0.1% compensation for the js/sol math differences + return auction.debtDAI.dividedBy(unitPrice).multipliedBy(1.001); } else if ( // if owe < tab && slice < lot potentialOutcomeTotalPrice.isLessThan(auction.debtDAI) && diff --git a/core/src/tracker.ts b/core/src/tracker.ts index 28d29194d..1487cd785 100644 --- a/core/src/tracker.ts +++ b/core/src/tracker.ts @@ -35,7 +35,7 @@ const trackTransaction = async function ( }); } catch (error: any) { notifier('error', { - content: `Transaction error: "${parseMetamaskError(error?.message)}"`, + content: `Transaction error: "${parseMetamaskError(error?.data?.message || error?.message)}"`, key: messageId, duration: DEFAULT_NOTIFICATION_DURATION, }); @@ -72,7 +72,9 @@ const trackTransaction = async function ( return confirmedTransactionReceipt.transactionHash; } catch (error: any) { notifier('error', { - content: `Transaction was rejected with error: "${parseMetamaskError(error?.message)}"`, + content: `Transaction was rejected with error: "${parseMetamaskError( + error?.data?.message || error?.message + )}"`, key: messageId, duration: DEFAULT_NOTIFICATION_DURATION, }); diff --git a/core/test/surplus-test.ts b/core/test/surplus-test.ts index f2ebdc8f0..9029da5fc 100644 --- a/core/test/surplus-test.ts +++ b/core/test/surplus-test.ts @@ -47,9 +47,11 @@ describe('Surplus Auction', () => { const auctions = await fetchActiveSurplusAuctions(network); const auction = auctions[0] as SurplusAuctionActive; const enrichedAucton = await enrichSurplusAuction(network, auction); - expect(enrichedAucton.marketUnitPrice?.toString()).to.equal('0.001395892836151232667549186'); + expect(enrichedAucton.marketUnitPrice?.toString()).to.equal('0.001395892836151232667549185678491851066262951'); expect(enrichedAucton.unitPrice?.toString()).to.equal('0.0005430260298973471'); - expect(enrichedAucton.marketUnitPriceToUnitPriceRatio?.toString()).to.equal('-0.61098300970253348099040009'); + expect(enrichedAucton.marketUnitPriceToUnitPriceRatio?.toString()).to.equal( + '-0.610983009702533480990400000000000000000000026' + ); }); it('enrichesAuctionWithMinimumBids', async () => { const network = TEST_NETWORK; diff --git a/core/test/vault-test.ts b/core/test/vault-test.ts index c86564159..df9b8a6c5 100644 --- a/core/test/vault-test.ts +++ b/core/test/vault-test.ts @@ -35,29 +35,29 @@ const compareVaultTransactionsNotLiquidated = ( expect(expected.network).to.eq(actual.network); expect(expected.nextPriceChange).to.deep.equalInAnyOrder(actual.nextPriceChange); - expect(expected.liquidationRatio).to.deep.equalInAnyOrder(actual.liquidationRatio); - expect(expected.collateralizationRatio).to.deep.equalInAnyOrder(actual.collateralizationRatio); - expect(expected.proximityToLiquidation).to.deep.equalInAnyOrder(actual.proximityToLiquidation); + expect(expected.liquidationRatio.toFixed()).to.eq(actual.liquidationRatio.toFixed()); + expect(expected.collateralizationRatio.toFixed()).to.eq(actual.collateralizationRatio.toFixed()); + expect(expected.proximityToLiquidation.toFixed()).to.eq(actual.proximityToLiquidation.toFixed()); expect(expected.id).to.eq(actual.id); - expect(expected.incentiveCombinedDai).to.deep.equalInAnyOrder(actual.incentiveCombinedDai); - expect(expected.incentiveRelativeDai).to.deep.equalInAnyOrder(actual.incentiveRelativeDai); - expect(expected.incentiveConstantDai).to.deep.equalInAnyOrder(actual.incentiveConstantDai); - expect(expected.grossProfitDai).to.deep.equalInAnyOrder(actual.grossProfitDai); + expect(expected.incentiveCombinedDai.toFixed()).to.eq(actual.incentiveCombinedDai.toFixed()); + expect(expected.incentiveRelativeDai.toFixed()).to.eq(actual.incentiveRelativeDai.toFixed()); + expect(expected.incentiveConstantDai.toFixed()).to.eq(actual.incentiveConstantDai.toFixed()); + expect(expected.grossProfitDai.toFixed()).to.eq(actual.grossProfitDai.toFixed()); // TODO: enable the check and fix the bug with inconsistent price received - // expect(expected.netProfitDai).to.deep.equalInAnyOrder(actual.netProfitDai); - expect(expected.stabilityFeeRate).to.deep.equalInAnyOrder(actual.stabilityFeeRate); - expect(expected.minUnitPrice).to.deep.equalInAnyOrder(actual.minUnitPrice); - expect(expected.maximumProtocolDebtDai).to.deep.equalInAnyOrder(actual.maximumProtocolDebtDai); - expect(expected.currentProtocolDebtDai).to.deep.equalInAnyOrder(actual.currentProtocolDebtDai); - expect(expected.currentCollateralDebtDai).to.deep.equalInAnyOrder(actual.currentCollateralDebtDai); - expect(expected.maximumCollateralDebtDai).to.deep.equalInAnyOrder(actual.maximumCollateralDebtDai); - expect(expected.debtDai).to.deep.equalInAnyOrder(actual.debtDai); - expect(expected.collateralAmount).to.deep.equalInAnyOrder(actual.collateralAmount); - expect(expected.currentUnitPrice).to.deep.equalInAnyOrder(actual.currentUnitPrice); - expect(expected.nextUnitPrice).to.deep.equalInAnyOrder(actual.nextUnitPrice); - expect(expected.initialDebtDai).to.deep.equalInAnyOrder(actual.initialDebtDai); - expect(expected.liquidationPenaltyRatio).to.deep.equalInAnyOrder(actual.liquidationPenaltyRatio); - expect(expected.minimalAuctionedDai).to.deep.equalInAnyOrder(actual.minimalAuctionedDai); + // expect(expected.netProfitDai.toFixed()).to.eq(actual.netProfitDai.toFixed()); + expect(expected.stabilityFeeRate.toFixed()).to.eq(actual.stabilityFeeRate.toFixed()); + expect(expected.minUnitPrice.toFixed()).to.eq(actual.minUnitPrice.toFixed()); + expect(expected.maximumProtocolDebtDai.toFixed()).to.eq(actual.maximumProtocolDebtDai.toFixed()); + expect(expected.currentProtocolDebtDai.toFixed()).to.eq(actual.currentProtocolDebtDai.toFixed()); + expect(expected.currentCollateralDebtDai.toFixed()).to.eq(actual.currentCollateralDebtDai.toFixed()); + expect(expected.maximumCollateralDebtDai.toFixed()).to.eq(actual.maximumCollateralDebtDai.toFixed()); + expect(expected.debtDai.toFixed()).to.eq(actual.debtDai.toFixed()); + expect(expected.collateralAmount.toFixed()).to.eq(actual.collateralAmount.toFixed()); + expect(expected.currentUnitPrice.toFixed()).to.eq(actual.currentUnitPrice.toFixed()); + expect(expected.nextUnitPrice.toFixed()).to.eq(actual.nextUnitPrice.toFixed()); + expect(expected.initialDebtDai.toFixed()).to.eq(actual.initialDebtDai.toFixed()); + expect(expected.liquidationPenaltyRatio.toFixed()).to.eq(actual.liquidationPenaltyRatio.toFixed()); + expect(expected.minimalAuctionedDai.toFixed()).to.eq(actual.minimalAuctionedDai.toFixed()); }; describe('Vaults', () => { @@ -82,8 +82,8 @@ describe('Vaults', () => { nextPriceChange: new Date('2022-09-09T10:00:00.000Z'), liquidationRatio: new BigNumber('1.45'), - collateralizationRatio: new BigNumber('3.204790430641710905476031356'), - proximityToLiquidation: new BigNumber('0.547552318511616565008415095'), + collateralizationRatio: new BigNumber('3.204790430641710905476031355953603471763531393'), + proximityToLiquidation: new BigNumber('0.547552318511616565008415094516004867207418444'), liquidationPenaltyRatio: new BigNumber('1.13'), minimalAuctionedDai: new BigNumber('15000'), id: 22025, @@ -141,8 +141,8 @@ describe('Vaults', () => { nextPriceChange: new Date('2022-06-13T11:00:00.000Z'), liquidationRatio: new BigNumber(1.7), - collateralizationRatio: new BigNumber('1.698313241866926788910221381'), - proximityToLiquidation: new BigNumber('-0.000993196126304112564617121'), + collateralizationRatio: new BigNumber('1.698313241866926788910221380759664664393806833'), + proximityToLiquidation: new BigNumber('-0.000993196126304112564617120755317536277614422'), liquidationPenaltyRatio: new BigNumber('1.13'), minimalAuctionedDai: new BigNumber('5000'), id: 27435, diff --git a/frontend/components/common/formatters/AnimatedNumber.vue b/frontend/components/common/formatters/AnimatedNumber.vue index 5b11eff68..9f92a5af9 100644 --- a/frontend/components/common/formatters/AnimatedNumber.vue +++ b/frontend/components/common/formatters/AnimatedNumber.vue @@ -1,12 +1,15 @@