From 7f50febfcdd072d7e5af067f8f67879353a0972d Mon Sep 17 00:00:00 2001 From: Daniel <80175477+dan437@users.noreply.github.com> Date: Tue, 6 Dec 2022 17:44:09 +0100 Subject: [PATCH] Ensure 0% slippage on Arbitrum for wrapping / unwrapping (#16778) * Contract addresses to lowercase * Use case insensitive checks in the shouldEnableDirectWrapping fn * Remove duplicated functions, move unit tests into the right location --- shared/constants/swaps.js | 11 +- shared/lib/swaps-utils.js | 11 +- shared/lib/swaps-utils.test.js | 227 ++++++++++++++++++++++++++++++ ui/pages/swaps/swaps.util.js | 98 ------------- ui/pages/swaps/swaps.util.test.js | 209 --------------------------- 5 files changed, 236 insertions(+), 320 deletions(-) create mode 100644 shared/lib/swaps-utils.test.js diff --git a/shared/constants/swaps.js b/shared/constants/swaps.js index 37f9e30d2..649312be5 100644 --- a/shared/constants/swaps.js +++ b/shared/constants/swaps.js @@ -74,17 +74,14 @@ export const OPTIMISM_SWAPS_TOKEN_OBJECT = { ...ETH_SWAPS_TOKEN_OBJECT }; // A gas value for ERC20 approve calls that should be sufficient for all ERC20 approve implementations export const DEFAULT_ERC20_APPROVE_GAS = '0x1d4c0'; +// Contract addresses below should be in lowercase. const MAINNET_CONTRACT_ADDRESS = '0x881d40237659c251811cec9c364ef91dc08d300c'; - const TESTNET_CONTRACT_ADDRESS = '0x881d40237659c251811cec9c364ef91dc08d300c'; - const BSC_CONTRACT_ADDRESS = '0x1a1ec25dc08e98e5e93f1104b5e5cdd298707d31'; - -// It's the same as we use for BSC. const POLYGON_CONTRACT_ADDRESS = '0x1a1ec25dc08e98e5e93f1104b5e5cdd298707d31'; const AVALANCHE_CONTRACT_ADDRESS = '0x1a1ec25dc08e98e5e93f1104b5e5cdd298707d31'; -const OPTIMISM_CONTRACT_ADDRESS = '0x9dDA6Ef3D919c9bC8885D5560999A3640431e8e6'; -const ARBITRUM_CONTRACT_ADDRESS = '0x9dDA6Ef3D919c9bC8885D5560999A3640431e8e6'; +const OPTIMISM_CONTRACT_ADDRESS = '0x9dda6ef3d919c9bc8885d5560999a3640431e8e6'; +const ARBITRUM_CONTRACT_ADDRESS = '0x9dda6ef3d919c9bc8885d5560999a3640431e8e6'; export const WETH_CONTRACT_ADDRESS = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; @@ -100,7 +97,7 @@ export const WAVAX_CONTRACT_ADDRESS = export const WETH_OPTIMISM_CONTRACT_ADDRESS = '0x4200000000000000000000000000000000000006'; export const WETH_ARBITRUM_CONTRACT_ADDRESS = - '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'; + '0x82af49447d8a07e3bd95bd0d56f35241523fbab1'; const SWAPS_TESTNET_CHAIN_ID = '0x539'; diff --git a/shared/lib/swaps-utils.js b/shared/lib/swaps-utils.js index c1393abe3..549c56a8e 100644 --- a/shared/lib/swaps-utils.js +++ b/shared/lib/swaps-utils.js @@ -12,6 +12,7 @@ import { } from '../constants/swaps'; import { SECOND } from '../constants/time'; import { isValidHexAddress } from '../modules/hexstring-utils'; +import { isEqualCaseInsensitive } from '../modules/string-utils'; import { addHexPrefix } from '../../app/scripts/lib/util'; import fetchWithCache from './fetch-with-cache'; import { decimalToHex } from './transactions-controller-utils'; @@ -184,13 +185,11 @@ export const shouldEnableDirectWrapping = ( } const wrappedToken = SWAPS_WRAPPED_TOKENS_ADDRESSES[chainId]; const nativeToken = SWAPS_CHAINID_DEFAULT_TOKEN_MAP[chainId]?.address; - const sourceTokenLowerCase = sourceToken.toLowerCase(); - const destinationTokenLowerCase = destinationToken.toLowerCase(); return ( - (sourceTokenLowerCase === wrappedToken && - destinationTokenLowerCase === nativeToken) || - (sourceTokenLowerCase === nativeToken && - destinationTokenLowerCase === wrappedToken) + (isEqualCaseInsensitive(sourceToken, wrappedToken) && + isEqualCaseInsensitive(destinationToken, nativeToken)) || + (isEqualCaseInsensitive(sourceToken, nativeToken) && + isEqualCaseInsensitive(destinationToken, wrappedToken)) ); }; diff --git a/shared/lib/swaps-utils.test.js b/shared/lib/swaps-utils.test.js new file mode 100644 index 000000000..5979f1e93 --- /dev/null +++ b/shared/lib/swaps-utils.test.js @@ -0,0 +1,227 @@ +import nock from 'nock'; +import { CHAIN_IDS } from '../constants/network'; +import { + SWAPS_CHAINID_DEFAULT_TOKEN_MAP, + WETH_CONTRACT_ADDRESS, + WBNB_CONTRACT_ADDRESS, + WMATIC_CONTRACT_ADDRESS, +} from '../constants/swaps'; +import { + TOKENS, + MOCK_TRADE_RESPONSE_2, +} from '../../ui/pages/swaps/swaps-util-test-constants'; +import { fetchTradesInfo, shouldEnableDirectWrapping } from './swaps-utils'; + +jest.mock('./storage-helpers', () => ({ + getStorageItem: jest.fn(), + setStorageItem: jest.fn(), +})); + +describe('Swaps Utils', () => { + afterEach(() => { + nock.cleanAll(); + }); + + describe('fetchTradesInfo', () => { + const expectedResult1 = { + zeroEx: { + trade: { + // the ethereum transaction data for the swap + data: '0xa6c3bf330000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000005591360f8c7640fea5771c9682d6b5ecb776e1f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021486a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005efe3c3b5dfc3a75ffc8add04bbdbac1e42fa234bf4549d8dab1bc44c8056eaf0e1dfe8600000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000001c4dc1600f3000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000005591360f8c7640fea5771c9682d6b5ecb776e1f800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000140000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000036691c4f426eb8f42f150ebde43069a31cb080ad000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000021486a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010400000000000000000000000000000000000000000000000000000000000000869584cd0000000000000000000000001000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000005efe201b', + from: '0x2369267687A84ac7B494daE2f1542C40E37f4455', + value: '0x14401eab384000', + to: '0x61935cbdd02287b511119ddb11aeb42f1593b7ef', + gas: '0xa', + gasPrice: undefined, + }, + sourceAmount: '10000000000000000', + destinationAmount: '2248687', + error: null, + fee: 0.875, + sourceToken: TOKENS[0].address, + destinationToken: TOKENS[1].address, + fetchTime: 553, + aggregator: 'zeroEx', + aggType: 'AGG', + approvalNeeded: { + data: '0x095ea7b300000000000000000000000095e6f48254609a6ee006f7d493c8e5fb97094cef0000000000000000000000000000000000000000004a817c7ffffffdabf41c00', + to: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + value: '0x0', + from: '0x2369267687A84ac7B494daE2f1542C40E37f4455', + gas: '0x12', + gasPrice: '0x34', + }, + maxGas: 10, + averageGas: 1, + slippage: '3', + }, + }; + const expectedResult2 = { + zeroEx: { + ...expectedResult1.zeroEx, + sourceAmount: '20000000000000000', + }, + }; + it('should fetch trade info on prod', async () => { + nock('https://swap.metaswap.codefi.network') + .get('/networks/1/trades') + .query(true) + .reply(200, MOCK_TRADE_RESPONSE_2); + + const result = await fetchTradesInfo( + { + TOKENS, + slippage: '3', + sourceToken: TOKENS[0].address, + destinationToken: TOKENS[1].address, + value: '2000000000000000000', + fromAddress: '0xmockAddress', + sourceSymbol: TOKENS[0].symbol, + sourceDecimals: TOKENS[0].decimals, + sourceTokenInfo: { ...TOKENS[0] }, + destinationTokenInfo: { ...TOKENS[1] }, + }, + { chainId: CHAIN_IDS.MAINNET }, + ); + expect(result).toStrictEqual(expectedResult2); + }); + }); + + describe('shouldEnableDirectWrapping', () => { + const randomTokenAddress = '0x881d40237659c251811cec9c364ef91234567890'; + + it('returns true if swapping from ETH to WETH', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.MAINNET, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.MAINNET]?.address, + WETH_CONTRACT_ADDRESS, + ), + ).toBe(true); + }); + + it('returns true if swapping from ETH with uppercase chars to WETH', () => { + const ethAddressWithUpperCaseChars = + '0X0000000000000000000000000000000000000000'; + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.MAINNET, + ethAddressWithUpperCaseChars, + WETH_CONTRACT_ADDRESS, + ), + ).toBe(true); + }); + + it('returns true if swapping from WETH to ETH', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.MAINNET, + WETH_CONTRACT_ADDRESS, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.MAINNET]?.address, + ), + ).toBe(true); + }); + + it('returns true if swapping from WETH with uppercase chars to ETH', () => { + const wethContractAddressWithUpperCaseChars = + '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.MAINNET, + wethContractAddressWithUpperCaseChars, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.MAINNET]?.address, + ), + ).toBe(true); + }); + + it('returns false if swapping from ETH to a non-WETH token', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.MAINNET, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.MAINNET]?.address, + randomTokenAddress, + ), + ).toBe(false); + }); + + it('returns true if swapping from BNB to WBNB', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.BSC, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.BSC]?.address, + WBNB_CONTRACT_ADDRESS, + ), + ).toBe(true); + }); + + it('returns true if swapping from WBNB to BNB', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.BSC, + WBNB_CONTRACT_ADDRESS, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.BSC]?.address, + ), + ).toBe(true); + }); + + it('returns false if swapping from BNB to a non-WBNB token', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.BSC, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.BSC]?.address, + randomTokenAddress, + ), + ).toBe(false); + }); + + it('returns true if swapping from MATIC to WMATIC', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.POLYGON, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.POLYGON]?.address, + WMATIC_CONTRACT_ADDRESS, + ), + ).toBe(true); + }); + + it('returns true if swapping from WMATIC to MATIC', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.POLYGON, + WMATIC_CONTRACT_ADDRESS, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.POLYGON]?.address, + ), + ).toBe(true); + }); + + it('returns false if swapping from MATIC to a non-WMATIC token', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.POLYGON, + SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.POLYGON]?.address, + randomTokenAddress, + ), + ).toBe(false); + }); + + it('returns false if a source token is undefined', () => { + expect( + shouldEnableDirectWrapping( + CHAIN_IDS.MAINNET, + undefined, + WETH_CONTRACT_ADDRESS, + ), + ).toBe(false); + }); + + it('returns false if a destination token is undefined', () => { + expect( + shouldEnableDirectWrapping(CHAIN_IDS.MAINNET, WETH_CONTRACT_ADDRESS), + ).toBe(false); + }); + + it('returns false if source and destination tokens are undefined', () => { + expect(shouldEnableDirectWrapping(CHAIN_IDS.MAINNET)).toBe(false); + }); + }); +}); diff --git a/ui/pages/swaps/swaps.util.js b/ui/pages/swaps/swaps.util.js index 0998b533f..15a4966cd 100644 --- a/ui/pages/swaps/swaps.util.js +++ b/ui/pages/swaps/swaps.util.js @@ -13,7 +13,6 @@ import { SWAPS_API_V2_BASE_URL, SWAPS_DEV_API_V2_BASE_URL, SWAPS_CLIENT_ID, - SWAPS_WRAPPED_TOKENS_ADDRESSES, } from '../../../shared/constants/swaps'; import { isSwapsDefaultTokenAddress, @@ -32,14 +31,10 @@ import { toPrecisionWithoutTrailingZeros, } from '../../../shared/lib/transactions-controller-utils'; import { - calcTokenValue, - constructTxParams, getBaseApi, - QUOTE_VALIDATORS, truthyString, validateData, } from '../../../shared/lib/swaps-utils'; -import { SECOND } from '../../../shared/constants/time'; import { sumHexes } from '../../helpers/utils/transactions.util'; const CACHE_REFRESH_FIVE_MINUTES = 300000; @@ -106,99 +101,6 @@ const SWAP_GAS_PRICE_VALIDATOR = [ }, ]; -export const shouldEnableDirectWrapping = ( - chainId, - sourceToken, - destinationToken, -) => { - if (!sourceToken || !destinationToken) { - return false; - } - const wrappedToken = SWAPS_WRAPPED_TOKENS_ADDRESSES[chainId]; - const nativeToken = SWAPS_CHAINID_DEFAULT_TOKEN_MAP[chainId]?.address; - const sourceTokenLowerCase = sourceToken.toLowerCase(); - const destinationTokenLowerCase = destinationToken.toLowerCase(); - return ( - (sourceTokenLowerCase === wrappedToken && - destinationTokenLowerCase === nativeToken) || - (sourceTokenLowerCase === nativeToken && - destinationTokenLowerCase === wrappedToken) - ); -}; - -export async function fetchTradesInfo( - { - slippage, - sourceToken, - sourceDecimals, - destinationToken, - value, - fromAddress, - exchangeList, - }, - { chainId }, -) { - const urlParams = { - destinationToken, - sourceToken, - sourceAmount: calcTokenValue(value, sourceDecimals).toString(10), - slippage, - timeout: SECOND * 10, - walletAddress: fromAddress, - }; - - if (exchangeList) { - urlParams.exchangeList = exchangeList; - } - if (shouldEnableDirectWrapping(chainId, sourceToken, destinationToken)) { - urlParams.enableDirectWrapping = true; - } - - const queryString = new URLSearchParams(urlParams).toString(); - const tradeURL = `${getBaseApi('trade', chainId)}${queryString}`; - const tradesResponse = await fetchWithCache( - tradeURL, - { method: 'GET', headers: clientIdHeader }, - { cacheRefreshTime: 0, timeout: SECOND * 15 }, - ); - const newQuotes = tradesResponse.reduce((aggIdTradeMap, quote) => { - if ( - quote.trade && - !quote.error && - validateData(QUOTE_VALIDATORS, quote, tradeURL) - ) { - const constructedTrade = constructTxParams({ - to: quote.trade.to, - from: quote.trade.from, - data: quote.trade.data, - amount: decimalToHex(quote.trade.value), - gas: decimalToHex(quote.maxGas), - }); - - let { approvalNeeded } = quote; - - if (approvalNeeded) { - approvalNeeded = constructTxParams({ - ...approvalNeeded, - }); - } - - return { - ...aggIdTradeMap, - [quote.aggregator]: { - ...quote, - slippage, - trade: constructedTrade, - approvalNeeded, - }, - }; - } - return aggIdTradeMap; - }, {}); - - return newQuotes; -} - export async function fetchToken(contractAddress, chainId) { const tokenUrl = getBaseApi('token', chainId); const token = await fetchWithCache( diff --git a/ui/pages/swaps/swaps.util.test.js b/ui/pages/swaps/swaps.util.test.js index 3a49bb35a..23ed3392a 100644 --- a/ui/pages/swaps/swaps.util.test.js +++ b/ui/pages/swaps/swaps.util.test.js @@ -4,7 +4,6 @@ import { CHAIN_IDS, CURRENCY_SYMBOLS } from '../../../shared/constants/network'; import { getSwapsTokensReceivedFromTxMeta } from '../../../shared/lib/transactions-controller-utils'; import { SWAPS_CHAINID_CONTRACT_ADDRESS_MAP, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP, WETH_CONTRACT_ADDRESS, WBNB_CONTRACT_ADDRESS, WMATIC_CONTRACT_ADDRESS, @@ -16,14 +15,9 @@ import { OPTIMISM, ARBITRUM, } from '../../../shared/constants/swaps'; -import { - fetchTradesInfo, - shouldEnableDirectWrapping, -} from '../../../shared/lib/swaps-utils'; import { TOKENS, EXPECTED_TOKENS_RESULT, - MOCK_TRADE_RESPONSE_2, AGGREGATOR_METADATA, TOP_ASSETS, } from './swaps-util-test-constants'; @@ -50,71 +44,6 @@ describe('Swaps Util', () => { nock.cleanAll(); }); - describe('fetchTradesInfo', () => { - const expectedResult1 = { - zeroEx: { - trade: { - // the ethereum transaction data for the swap - data: '0xa6c3bf330000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000005591360f8c7640fea5771c9682d6b5ecb776e1f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021486a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005efe3c3b5dfc3a75ffc8add04bbdbac1e42fa234bf4549d8dab1bc44c8056eaf0e1dfe8600000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000001c4dc1600f3000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000005591360f8c7640fea5771c9682d6b5ecb776e1f800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000140000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000036691c4f426eb8f42f150ebde43069a31cb080ad000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000021486a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010400000000000000000000000000000000000000000000000000000000000000869584cd0000000000000000000000001000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000005efe201b', - from: '0x2369267687A84ac7B494daE2f1542C40E37f4455', - value: '0x14401eab384000', - to: '0x61935cbdd02287b511119ddb11aeb42f1593b7ef', - gas: '0xa', - gasPrice: undefined, - }, - sourceAmount: '10000000000000000', - destinationAmount: '2248687', - error: null, - fee: 0.875, - sourceToken: TOKENS[0].address, - destinationToken: TOKENS[1].address, - fetchTime: 553, - aggregator: 'zeroEx', - aggType: 'AGG', - approvalNeeded: { - data: '0x095ea7b300000000000000000000000095e6f48254609a6ee006f7d493c8e5fb97094cef0000000000000000000000000000000000000000004a817c7ffffffdabf41c00', - to: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - value: '0x0', - from: '0x2369267687A84ac7B494daE2f1542C40E37f4455', - gas: '0x12', - gasPrice: '0x34', - }, - maxGas: 10, - averageGas: 1, - slippage: '3', - }, - }; - const expectedResult2 = { - zeroEx: { - ...expectedResult1.zeroEx, - sourceAmount: '20000000000000000', - }, - }; - it('should fetch trade info on prod', async () => { - nock('https://swap.metaswap.codefi.network') - .get('/networks/1/trades') - .query(true) - .reply(200, MOCK_TRADE_RESPONSE_2); - - const result = await fetchTradesInfo( - { - TOKENS, - slippage: '3', - sourceToken: TOKENS[0].address, - destinationToken: TOKENS[1].address, - value: '2000000000000000000', - fromAddress: '0xmockAddress', - sourceSymbol: TOKENS[0].symbol, - sourceDecimals: TOKENS[0].decimals, - sourceTokenInfo: { ...TOKENS[0] }, - destinationTokenInfo: { ...TOKENS[1] }, - }, - { chainId: CHAIN_IDS.MAINNET }, - ); - expect(result).toStrictEqual(expectedResult2); - }); - }); - describe('fetchTokens', () => { beforeEach(() => { nock('https://swap.metaswap.codefi.network') @@ -414,144 +343,6 @@ describe('Swaps Util', () => { }); }); - describe('shouldEnableDirectWrapping', () => { - const randomTokenAddress = '0x881d40237659c251811cec9c364ef91234567890'; - - it('returns true if swapping from ETH to WETH', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.MAINNET, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.MAINNET]?.address, - WETH_CONTRACT_ADDRESS, - ), - ).toBe(true); - }); - - it('returns true if swapping from ETH with uppercase chars to WETH', () => { - const ethAddressWithUpperCaseChars = - '0X0000000000000000000000000000000000000000'; - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.MAINNET, - ethAddressWithUpperCaseChars, - WETH_CONTRACT_ADDRESS, - ), - ).toBe(true); - }); - - it('returns true if swapping from WETH to ETH', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.MAINNET, - WETH_CONTRACT_ADDRESS, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.MAINNET]?.address, - ), - ).toBe(true); - }); - - it('returns true if swapping from WETH with uppercase chars to ETH', () => { - const wethContractAddressWithUpperCaseChars = - '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.MAINNET, - wethContractAddressWithUpperCaseChars, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.MAINNET]?.address, - ), - ).toBe(true); - }); - - it('returns false if swapping from ETH to a non-WETH token', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.MAINNET, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.MAINNET]?.address, - randomTokenAddress, - ), - ).toBe(false); - }); - - it('returns true if swapping from BNB to WBNB', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.BSC, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.BSC]?.address, - WBNB_CONTRACT_ADDRESS, - ), - ).toBe(true); - }); - - it('returns true if swapping from WBNB to BNB', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.BSC, - WBNB_CONTRACT_ADDRESS, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.BSC]?.address, - ), - ).toBe(true); - }); - - it('returns false if swapping from BNB to a non-WBNB token', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.BSC, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.BSC]?.address, - randomTokenAddress, - ), - ).toBe(false); - }); - - it('returns true if swapping from MATIC to WMATIC', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.POLYGON, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.POLYGON]?.address, - WMATIC_CONTRACT_ADDRESS, - ), - ).toBe(true); - }); - - it('returns true if swapping from WMATIC to MATIC', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.POLYGON, - WMATIC_CONTRACT_ADDRESS, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.POLYGON]?.address, - ), - ).toBe(true); - }); - - it('returns false if swapping from MATIC to a non-WMATIC token', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.POLYGON, - SWAPS_CHAINID_DEFAULT_TOKEN_MAP[CHAIN_IDS.POLYGON]?.address, - randomTokenAddress, - ), - ).toBe(false); - }); - - it('returns false if a source token is undefined', () => { - expect( - shouldEnableDirectWrapping( - CHAIN_IDS.MAINNET, - undefined, - WETH_CONTRACT_ADDRESS, - ), - ).toBe(false); - }); - - it('returns false if a destination token is undefined', () => { - expect( - shouldEnableDirectWrapping(CHAIN_IDS.MAINNET, WETH_CONTRACT_ADDRESS), - ).toBe(false); - }); - - it('returns false if source and destination tokens are undefined', () => { - expect(shouldEnableDirectWrapping(CHAIN_IDS.MAINNET)).toBe(false); - }); - }); - describe('showRemainingTimeInMinAndSec', () => { it('returns 0:00 if we do not pass an integer', () => { expect(showRemainingTimeInMinAndSec('5')).toBe('0:00');