Skip to content

Commit

Permalink
Remove bignumber.js package
Browse files Browse the repository at this point in the history
Compare second simulation response using threshold.
Change percentage difference to percentage change.
  • Loading branch information
matthewwalsh0 committed Oct 25, 2024
1 parent d823fc2 commit 2e29bf3
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 120 deletions.
8 changes: 4 additions & 4 deletions packages/transaction-controller/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ module.exports = merge(baseConfig, {
// An object that configures minimum threshold enforcement for coverage results
coverageThreshold: {
global: {
branches: 94.02,
functions: 97.49,
lines: 98.36,
statements: 98.37,
branches: 93.87,
functions: 97.51,
lines: 98.38,
statements: 98.39,
},
},

Expand Down
1 change: 0 additions & 1 deletion packages/transaction-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
"@metamask/rpc-errors": "^7.0.0",
"@metamask/utils": "^9.1.0",
"async-mutex": "^0.5.0",
"bignumber.js": "^9.1.2",
"bn.js": "^5.2.1",
"eth-method-registry": "^4.0.0",
"fast-json-patch": "^3.1.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/transaction-controller/src/TransactionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import { add0x } from '@metamask/utils';
import { Mutex } from 'async-mutex';
import { MethodRegistry } from 'eth-method-registry';
import { EventEmitter } from 'events';
import { cloneDeep, mapValues, merge, pickBy, sortBy, isEqual } from 'lodash';
import { cloneDeep, mapValues, merge, pickBy, sortBy } from 'lodash';
import { v1 as random } from 'uuid';

import { DefaultGasFeeFlow } from './gas-flows/DefaultGasFeeFlow';
Expand Down Expand Up @@ -106,7 +106,7 @@ import {
getNextNonce,
} from './utils/nonce';
import type { ResimulateResponse } from './utils/resimulate';
import { shouldResimulate } from './utils/resimulate';
import { hasSimulationDataChanged, shouldResimulate } from './utils/resimulate';
import { getTransactionParamsWithIncreasedGasFee } from './utils/retry';
import { getSimulationData } from './utils/simulation';
import {
Expand Down Expand Up @@ -3667,7 +3667,7 @@ export class TransactionController extends BaseController<
if (
blockTime &&
prevSimulationData &&
!isEqual(simulationData, prevSimulationData)
hasSimulationDataChanged(prevSimulationData, simulationData)
) {
simulationData = {
...simulationData,
Expand Down
154 changes: 136 additions & 18 deletions packages/transaction-controller/src/utils/resimulate.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { BN } from 'bn.js';

import { CHAIN_IDS } from '../constants';
import type {
SecurityAlertResponse,
SimulationData,
SimulationTokenBalanceChange,
TransactionMeta,
} from '../types';
import { TransactionStatus } from '../types';
import { SimulationTokenStandard, TransactionStatus } from '../types';
import {
BLOCK_TIME_ADDITIONAL_SECONDS,
BLOCKAID_RESULT_TYPE_MALICIOUS,
hasSimulationDataChanged,
RESIMULATE_PARAMS,
shouldResimulate,
VALUE_NATIVE_BALANCE_PERCENT_THRESHOLD,
VALUE_COMPARISON_PERCENT_THRESHOLD,
} from './resimulate';
import { isPercentageDifferenceWithinThreshold } from './utils';
import { getPercentageChange } from './utils';

jest.mock('./utils');

Expand All @@ -25,6 +29,15 @@ const SECURITY_ALERT_RESPONSE_MOCK: SecurityAlertResponse = {
result_type: 'TestResultType',
};

const TOKEN_BALANCE_CHANGE_MOCK: SimulationTokenBalanceChange = {
address: '0x1',
standard: SimulationTokenStandard.erc20,
difference: '0x1',
previousBalance: '0x1',
newBalance: '0x2',
isDecrease: false,
};

const SIMULATION_DATA_MOCK: SimulationData = {
nativeBalanceChange: {
difference: '0x1',
Expand All @@ -35,6 +48,16 @@ const SIMULATION_DATA_MOCK: SimulationData = {
tokenBalanceChanges: [],
};

const SIMULATION_DATA_2_MOCK: SimulationData = {
nativeBalanceChange: {
difference: '0x1',
previousBalance: '0x2',
newBalance: '0x3',
isDecrease: false,
},
tokenBalanceChanges: [],
};

const TRANSACTION_META_MOCK: TransactionMeta = {
chainId: CHAIN_IDS.MAINNET,
id: '123-456',
Expand All @@ -50,13 +73,13 @@ const TRANSACTION_META_MOCK: TransactionMeta = {
};

describe('Resimulate Utils', () => {
const isPercentageDifferenceWithinThresholdMock = jest.mocked(
isPercentageDifferenceWithinThreshold,
);
const getPercentageChangeMock = jest.mocked(getPercentageChange);

beforeEach(() => {
jest.resetAllMocks();
jest.spyOn(Date, 'now').mockReturnValue(CURRENT_TIME_MOCK);

getPercentageChangeMock.mockReturnValue(0);
});

describe('shouldResimulate', () => {
Expand Down Expand Up @@ -149,7 +172,9 @@ describe('Resimulate Utils', () => {

describe('Value & Native Balance', () => {
it('resimulates if value does not match native balance difference from simulation', () => {
isPercentageDifferenceWithinThresholdMock.mockReturnValue(false);
getPercentageChangeMock.mockReturnValueOnce(
VALUE_COMPARISON_PERCENT_THRESHOLD + 1,
);

const result = shouldResimulate(TRANSACTION_META_MOCK, {
...TRANSACTION_META_MOCK,
Expand All @@ -160,7 +185,9 @@ describe('Resimulate Utils', () => {
});

it('includes block time if value does not match native balance difference from simulation', () => {
isPercentageDifferenceWithinThresholdMock.mockReturnValue(false);
getPercentageChangeMock.mockReturnValueOnce(
VALUE_COMPARISON_PERCENT_THRESHOLD + 1,
);

const result = shouldResimulate(TRANSACTION_META_MOCK, {
...TRANSACTION_META_MOCK,
Expand All @@ -173,7 +200,7 @@ describe('Resimulate Utils', () => {
});

it('does not resimulate if simulation data changed but value and native balance match', () => {
isPercentageDifferenceWithinThresholdMock.mockReturnValue(true);
getPercentageChangeMock.mockReturnValueOnce(0);

const result = shouldResimulate(TRANSACTION_META_MOCK, {
...TRANSACTION_META_MOCK,
Expand All @@ -187,8 +214,6 @@ describe('Resimulate Utils', () => {
});

it('does not resimulate if simulation data changed but value and native balance not specified', () => {
isPercentageDifferenceWithinThresholdMock.mockReturnValue(true);

const result = shouldResimulate(
{
...TRANSACTION_META_MOCK,
Expand All @@ -210,13 +235,10 @@ describe('Resimulate Utils', () => {
},
);

expect(isPercentageDifferenceWithinThresholdMock).toHaveBeenCalledTimes(
1,
);
expect(isPercentageDifferenceWithinThresholdMock).toHaveBeenCalledWith(
'0x0',
'0x0',
VALUE_NATIVE_BALANCE_PERCENT_THRESHOLD,
expect(getPercentageChangeMock).toHaveBeenCalledTimes(1);
expect(getPercentageChangeMock).toHaveBeenCalledWith(
new BN(0),
new BN(0),
);

expect(result).toStrictEqual({
Expand All @@ -226,4 +248,100 @@ describe('Resimulate Utils', () => {
});
});
});

describe('hasSimulationDataChanged', () => {
it('returns false if simulation data unchanged', () => {
const result = hasSimulationDataChanged(
SIMULATION_DATA_MOCK,
SIMULATION_DATA_MOCK,
);

expect(result).toBe(false);
});

it('returns true if native balance changed', () => {
getPercentageChangeMock.mockReturnValueOnce(
VALUE_COMPARISON_PERCENT_THRESHOLD + 1,
);

const result = hasSimulationDataChanged(
SIMULATION_DATA_MOCK,
SIMULATION_DATA_2_MOCK,
);

expect(result).toBe(true);
});

it('returns true if token balance count does not match', () => {
getPercentageChangeMock.mockReturnValueOnce(0);

const result = hasSimulationDataChanged(SIMULATION_DATA_MOCK, {
...SIMULATION_DATA_MOCK,
tokenBalanceChanges: [TOKEN_BALANCE_CHANGE_MOCK],
});

expect(result).toBe(true);
});

it('returns true if token balance does not match', () => {
getPercentageChangeMock
.mockReturnValueOnce(0)
.mockReturnValueOnce(VALUE_COMPARISON_PERCENT_THRESHOLD + 1);

const result = hasSimulationDataChanged(
{
...SIMULATION_DATA_MOCK,
tokenBalanceChanges: [TOKEN_BALANCE_CHANGE_MOCK],
},
{
...SIMULATION_DATA_MOCK,
tokenBalanceChanges: [
{ ...TOKEN_BALANCE_CHANGE_MOCK, difference: '0x2' },
],
},
);

expect(result).toBe(true);
});

it('returns false if token balance changed but within threshold', () => {
getPercentageChangeMock
.mockReturnValueOnce(0)
.mockReturnValueOnce(VALUE_COMPARISON_PERCENT_THRESHOLD);

const result = hasSimulationDataChanged(
{
...SIMULATION_DATA_MOCK,
tokenBalanceChanges: [TOKEN_BALANCE_CHANGE_MOCK],
},
{
...SIMULATION_DATA_MOCK,
tokenBalanceChanges: [
{ ...TOKEN_BALANCE_CHANGE_MOCK, difference: '0x2' },
],
},
);

expect(result).toBe(false);
});

it('returns true if new token balance not found', () => {
getPercentageChangeMock.mockReturnValueOnce(0).mockReturnValueOnce(0);

const result = hasSimulationDataChanged(
{
...SIMULATION_DATA_MOCK,
tokenBalanceChanges: [TOKEN_BALANCE_CHANGE_MOCK],
},
{
...SIMULATION_DATA_MOCK,
tokenBalanceChanges: [
{ ...TOKEN_BALANCE_CHANGE_MOCK, address: '0x2' },
],
},
);

expect(result).toBe(true);
});
});
});
Loading

0 comments on commit 2e29bf3

Please sign in to comment.