Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@metamask/approval-controller": "^5.1.1",
"@metamask/network-controller": "^17.1.0",
"@metamask/transaction-controller": "^19.0.1",
"@types/bn.js": "^5.1.5",
"@types/jest": "^26.0.22",
"@types/node": "^20.10.4",
"@typescript-eslint/eslint-plugin": "^5.42.1",
Expand Down Expand Up @@ -77,7 +78,6 @@
"@metamask/utils": "^8.3.0",
"abort-controller": "^3.0.0",
"async-mutex": "^0.4.1",
"bignumber.js": "^9.0.1",
"bn.js": "^5.2.1",
"human-standard-token-abi": "^2.0.0",
"web3": "^4.2.2"
Expand Down
93 changes: 44 additions & 49 deletions src/SwapsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller';
import type { TransactionParams } from '@metamask/transaction-controller';
import type { Hex } from '@metamask/utils';
import { Mutex } from 'async-mutex';
import { BigNumber } from 'bignumber.js';
import BN from 'bn.js';
import abiERC20 from 'human-standard-token-abi';
import * as web3 from 'web3';
import type { Web3 as Web3Type } from 'web3';
Expand Down Expand Up @@ -335,27 +335,25 @@ export default class SwapsController extends BaseControllerV1<
gasLimit,
);

let totalGasInWei: BigNumber;
let maxTotalGasInWei: BigNumber;
let totalGasInWei: BN;
let maxTotalGasInWei: BN;

if (isEthGasPriceEstimate(gasFeeEstimates)) {
const gasPrice = isCustomEthGasPriceEstimate(customGasFee)
? customGasFee.gasPrice
: gasFeeEstimates.gasPrice;

totalGasInWei = tradeGasLimit.times(
gweiDecToWEIBN(gasPrice).toString(16),
16,
);
totalGasInWei = tradeGasLimit.mul(gweiDecToWEIBN(gasPrice));

maxTotalGasInWei = new BigNumber(tradeMaxGasLimit).times(
gweiDecToWEIBN(gasPrice).toString(16),
16,
);
maxTotalGasInWei = new BN(tradeMaxGasLimit).mul(gweiDecToWEIBN(gasPrice));

if (multiLayerL1TradeFeeTotal) {
totalGasInWei = totalGasInWei.plus(multiLayerL1TradeFeeTotal, 16);
maxTotalGasInWei = maxTotalGasInWei.plus(multiLayerL1TradeFeeTotal, 16);
totalGasInWei = totalGasInWei.add(
new BN(multiLayerL1TradeFeeTotal, 16),
);
maxTotalGasInWei = maxTotalGasInWei.add(
new BN(multiLayerL1TradeFeeTotal, 16),
);
}
} else {
const estimatedBaseFee =
Expand All @@ -369,16 +367,14 @@ export default class SwapsController extends BaseControllerV1<
gasFeeEstimates.high.suggestedMaxPriorityFeePerGas,
];

totalGasInWei = tradeGasLimit.times(
gweiDecToWEIBN(estimatedBaseFee)
.add(gweiDecToWEIBN(maxPriorityFeePerGas))
.toString(16),
16,
totalGasInWei = tradeGasLimit.mul(
gweiDecToWEIBN(estimatedBaseFee).add(
gweiDecToWEIBN(maxPriorityFeePerGas),
),
);

maxTotalGasInWei = new BigNumber(tradeMaxGasLimit).times(
gweiDecToWEIBN(maxFeePerGas).toString(16),
16,
maxTotalGasInWei = new BN(tradeMaxGasLimit).mul(
gweiDecToWEIBN(maxFeePerGas),
);
}

Expand All @@ -387,17 +383,17 @@ export default class SwapsController extends BaseControllerV1<
// It always includes any external fees charged by the quote source. In
// addition, if the source asset is NATIVE, trade.value includes the amount
// of swapped NATIVE.
const totalInWei = totalGasInWei.plus(trade.value, 16);
const maxTotalInWei = maxTotalGasInWei.plus(trade.value, 16);
const totalInWei = totalGasInWei.add(new BN(trade.value, 16));
const maxTotalInWei = maxTotalGasInWei.add(new BN(trade.value, 16));

// if value in trade, NATIVE fee will be the gas, if not it will be the total wei
const weiFee =
sourceToken === NATIVE_SWAPS_TOKEN_ADDRESS
? totalInWei.minus(sourceAmount, 10)
? totalInWei.sub(new BN(sourceAmount, 10))
: totalInWei; // sourceAmount is in wei : totalInWei;
const maxWeiFee =
sourceToken === NATIVE_SWAPS_TOKEN_ADDRESS
? maxTotalInWei.minus(sourceAmount, 10)
? maxTotalInWei.sub(new BN(sourceAmount, 10))
: maxTotalInWei; // sourceAmount is in wei : totalInWei;
const ethFee = calcTokenAmount(weiFee, 18);
const maxEthFee = calcTokenAmount(maxWeiFee, 18);
Expand All @@ -408,34 +404,34 @@ export default class SwapsController extends BaseControllerV1<
);

// fees
const tokenPercentageOfPreFeeDestAmount = new BigNumber(100, 10)
.minus(metaMaskFee, 10)
.div(100);
const tokenPercentageOfPreFeeDestAmount = new BN(100, 10)
.subn(metaMaskFee)
.divn(100);
const destinationAmountBeforeMetaMaskFee =
decimalAdjustedDestinationAmount.div(tokenPercentageOfPreFeeDestAmount);
const metaMaskFeeInTokens = destinationAmountBeforeMetaMaskFee.minus(
const metaMaskFeeInTokens = destinationAmountBeforeMetaMaskFee.sub(
decimalAdjustedDestinationAmount,
);

const conversionRate = destinationTokenRate ?? 1;

const ethValueOfTokens = decimalAdjustedDestinationAmount.times(
conversionRate,
10,
);
const ethValueOfTokens =
decimalAdjustedDestinationAmount.muln(conversionRate);

// the more tokens the better
const overallValueOfQuote = ethValueOfTokens.minus(ethFee, 10);
const overallValueOfQuote = ethValueOfTokens.sub(ethFee);

const quoteValues: QuoteValues = {
aggregator,
tradeGasLimit: tradeGasLimit.toString(10),
tradeMaxGasLimit: tradeMaxGasLimit.toString(10),
ethFee: ethFee.toFixed(18),
maxEthFee: maxEthFee.toFixed(18),
ethValueOfTokens: ethValueOfTokens.toFixed(18),
overallValueOfQuote: overallValueOfQuote.toFixed(18),
metaMaskFeeInEth: metaMaskFeeInTokens.times(conversionRate).toFixed(18),
ethFee: ethFee.toString(10, 18),
maxEthFee: maxEthFee.toString(10, 18),
ethValueOfTokens: ethValueOfTokens.toString(10, 18),
overallValueOfQuote: overallValueOfQuote.toString(10, 18),
metaMaskFeeInEth: metaMaskFeeInTokens
.muln(conversionRate)
.toString(10, 18),
};

return quoteValues;
Expand Down Expand Up @@ -482,16 +478,17 @@ export default class SwapsController extends BaseControllerV1<
gasPrice = gasFee.high.suggestedMaxFeePerGas;
}

const maxTotalGasInWei = new BigNumber(tradeMaxGasLimit).times(
gweiDecToWEIBN(gasPrice).toString(16),
16,
const maxTotalGasInWei = new BN(tradeMaxGasLimit).mul(
gweiDecToWEIBN(gasPrice),
);
const maxTotalInWei = maxTotalGasInWei.add(
new BN(trade.value ?? '0x0', 16),
);
const maxTotalInWei = maxTotalGasInWei.plus(trade.value ?? '0x0', 16);
const maxWeiFee =
sourceToken === NATIVE_SWAPS_TOKEN_ADDRESS
? maxTotalInWei.minus(sourceAmount, 10)
? maxTotalInWei.sub(new BN(sourceAmount, 10))
: maxTotalInWei;
const maxEthFee = calcTokenAmount(maxWeiFee, 18).toFixed(18);
const maxEthFee = calcTokenAmount(maxWeiFee, 18).toString(10, 18);
return maxEthFee;
}

Expand All @@ -507,7 +504,7 @@ export default class SwapsController extends BaseControllerV1<
customGasFee?: CustomEthGasPriceEstimate | CustomGasFee,
): { topAggId: string; quoteValues: { [key: string]: QuoteValues } } {
let topAggId = '';
let overallValueOfBestQuoteForSorting: BigNumber | null = null;
let overallValueOfBestQuoteForSorting: BN | null = null;

const quoteValues: { [key: string]: QuoteValues } = {};

Expand All @@ -520,9 +517,7 @@ export default class SwapsController extends BaseControllerV1<
);
quoteValues[quoteValue.aggregator] = quoteValue;

const bnOverallValueOfQuote = new BigNumber(
quoteValue.overallValueOfQuote,
);
const bnOverallValueOfQuote = new BN(quoteValue.overallValueOfQuote);
if (
!overallValueOfBestQuoteForSorting ||
bnOverallValueOfQuote.gt(overallValueOfBestQuoteForSorting)
Expand Down
10 changes: 5 additions & 5 deletions src/swapsInterfaces.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { TransactionParams } from '@metamask/transaction-controller';
import type { BigNumber } from 'bignumber.js';
import type BN from 'bn.js';

export enum APIType {
TRADES = 'TRADES',
Expand Down Expand Up @@ -123,10 +123,10 @@ type QuoteTransaction = {
* @interface QuoteSavings
*/
export type QuoteSavings = {
total: BigNumber;
performance: BigNumber;
fee: BigNumber;
medianMetaMaskFee: BigNumber;
total: BN;
performance: BN;
fee: BN;
medianMetaMaskFee: BN;
};

/**
Expand Down
25 changes: 13 additions & 12 deletions src/swapsUtil.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BigNumber } from 'bignumber.js';
import BN from 'bn.js';
import { remove0x } from '@metamask/utils';

import type { SwapsToken } from './swapsInterfaces';
import { APIType } from './swapsInterfaces';
Expand Down Expand Up @@ -727,24 +728,24 @@ describe('SwapsUtil', () => {
});

describe('getMedian', () => {
const numbers = [...Array(9).keys()].map((i) => new BigNumber(i + 1));
const largeNumbers = numbers.map((i) => i.multipliedBy(100));
const numbers = [...Array(9).keys()].map((i) => new BN(i + 1));
const largeNumbers = numbers.map((i) => i.muln(100));

it.each([
[numbers, '5'],
[largeNumbers, '500'],
])('returns the middle value', (values, result) => {
const middleValue = swapsUtil.getMedian(values);
expect(middleValue).toBeInstanceOf(BigNumber);
expect(middleValue).toBeInstanceOf(BN);
expect(middleValue.toString(10)).toBe(result);
});

it.each([
[[...numbers, new BigNumber(10)], '5.5'],
[[...largeNumbers, new BigNumber(1000)], '550'],
[[...numbers, new BN(10)], '5.5'],
[[...largeNumbers, new BN(1000)], '550'],
])('returns the median value', (values, result) => {
const medianValue = swapsUtil.getMedian(values);
expect(medianValue).toBeInstanceOf(BigNumber);
expect(medianValue).toBeInstanceOf(BN);
expect(medianValue.toString(10)).toBe(result);
});

Expand Down Expand Up @@ -803,10 +804,10 @@ describe('SwapsUtil', () => {
gasMultiplier,
null,
);
const limit: BigNumber = new BigNumber(gasEstimateWithRefund);
const limit: BN = new BN(gasEstimateWithRefund);
expect(tradeGasLimit.toString(16)).toStrictEqual(limit.toString(16));
expect(tradeMaxGasLimit.toString(16)).toStrictEqual(
new BigNumber(gasEstimate).times(gasMultiplier).toString(16),
new BN(gasEstimate).muln(gasMultiplier).toString(16),
);
});

Expand All @@ -822,7 +823,7 @@ describe('SwapsUtil', () => {
);
expect(tradeGasLimit.toString()).toStrictEqual(averageGas.toString());
expect(tradeMaxGasLimit.toString(16)).toStrictEqual(
new BigNumber(customGasLimit).toString(16),
new BN(customGasLimit).toString(16),
);
});

Expand All @@ -836,10 +837,10 @@ describe('SwapsUtil', () => {
gasMultiplier,
customGasLimit,
);
const limit: BigNumber = new BigNumber(gasEstimateWithRefund);
const limit: BN = new BN(remove0x(gasEstimateWithRefund));
expect(tradeGasLimit.toString(16)).toStrictEqual(limit.toString(16));
expect(tradeMaxGasLimit.toString(16)).toStrictEqual(
new BigNumber(customGasLimit).toString(16),
new BN(remove0x(customGasLimit)).toString(16),
);
});
});
Expand Down
Loading