@ -2,12 +2,14 @@ import assert from 'assert'
import sinon from 'sinon'
import sinon from 'sinon'
import { ethers } from 'ethers'
import { ethers } from 'ethers'
import { mapValues } from 'lodash'
import BigNumber from 'bignumber.js'
import BigNumber from 'bignumber.js'
import ObservableStore from 'obs-store'
import ObservableStore from 'obs-store'
import {
import {
ROPSTEN _NETWORK _ID ,
ROPSTEN _NETWORK _ID ,
MAINNET _NETWORK _ID ,
MAINNET _NETWORK _ID ,
} from '../../../../app/scripts/controllers/network/enums'
} from '../../../../app/scripts/controllers/network/enums'
import { ETH _SWAPS _TOKEN _ADDRESS } from '../../../../ui/app/helpers/constants/swaps'
import { createTestProviderTools } from '../../../stub/provider'
import { createTestProviderTools } from '../../../stub/provider'
import SwapsController , {
import SwapsController , {
utils ,
utils ,
@ -25,6 +27,10 @@ const MOCK_FETCH_PARAMS = {
const TEST _AGG _ID _1 = 'TEST_AGG_1'
const TEST _AGG _ID _1 = 'TEST_AGG_1'
const TEST _AGG _ID _2 = 'TEST_AGG_2'
const TEST _AGG _ID _2 = 'TEST_AGG_2'
const TEST _AGG _ID _3 = 'TEST_AGG_3'
const TEST _AGG _ID _4 = 'TEST_AGG_4'
const TEST _AGG _ID _5 = 'TEST_AGG_5'
const TEST _AGG _ID _6 = 'TEST_AGG_6'
const TEST _AGG _ID _BEST = 'TEST_AGG_BEST'
const TEST _AGG _ID _BEST = 'TEST_AGG_BEST'
const TEST _AGG _ID _APPROVAL = 'TEST_AGG_APPROVAL'
const TEST _AGG _ID _APPROVAL = 'TEST_AGG_APPROVAL'
@ -61,6 +67,7 @@ const MOCK_QUOTES_APPROVAL_REQUIRED = {
aggType : 'AGG' ,
aggType : 'AGG' ,
slippage : 3 ,
slippage : 3 ,
approvalNeeded : MOCK _APPROVAL _NEEDED ,
approvalNeeded : MOCK _APPROVAL _NEEDED ,
fee : 1 ,
} ,
} ,
}
}
@ -72,7 +79,10 @@ const MOCK_FETCH_METADATA = {
}
}
const MOCK _TOKEN _RATES _STORE = new ObservableStore ( {
const MOCK _TOKEN _RATES _STORE = new ObservableStore ( {
contractExchangeRates : { '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' : 2 } ,
contractExchangeRates : {
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' : 2 ,
'0x1111111111111111111111111111111111111111' : 0.1 ,
} ,
} )
} )
const MOCK _GET _PROVIDER _CONFIG = ( ) => ( { type : 'FAKE_NETWORK' } )
const MOCK _GET _PROVIDER _CONFIG = ( ) => ( { type : 'FAKE_NETWORK' } )
@ -350,6 +360,13 @@ describe('SwapsController', function () {
} )
} )
describe ( '_findTopQuoteAndCalculateSavings' , function ( ) {
describe ( '_findTopQuoteAndCalculateSavings' , function ( ) {
beforeEach ( function ( ) {
const { swapsState } = swapsController . store . getState ( )
swapsController . store . updateState ( {
swapsState : { ... swapsState , customGasPrice : '0x174876e800' } ,
} )
} )
it ( 'returns empty object if passed undefined or empty object' , async function ( ) {
it ( 'returns empty object if passed undefined or empty object' , async function ( ) {
assert . deepStrictEqual (
assert . deepStrictEqual (
await swapsController . _findTopQuoteAndCalculateSavings ( ) ,
await swapsController . _findTopQuoteAndCalculateSavings ( ) ,
@ -360,6 +377,261 @@ describe('SwapsController', function () {
{ } ,
{ } ,
)
)
} )
} )
it ( 'returns the top aggId and quotes with savings and fee values if passed necessary data and an even number of quotes' , async function ( ) {
const [
topAggId ,
resultQuotes ,
] = await swapsController . _findTopQuoteAndCalculateSavings (
getTopQuoteAndSavingsMockQuotes ( ) ,
)
assert . equal ( topAggId , TEST _AGG _ID _1 )
assert . deepStrictEqual (
resultQuotes ,
getTopQuoteAndSavingsBaseExpectedResults ( ) ,
)
} )
it ( 'returns the top aggId and quotes with savings and fee values if passed necessary data and an odd number of quotes' , async function ( ) {
const testInput = getTopQuoteAndSavingsMockQuotes ( )
delete testInput [ TEST _AGG _ID _6 ]
const expectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults ( )
delete expectedResultQuotes [ TEST _AGG _ID _6 ]
expectedResultQuotes [ TEST _AGG _ID _1 ] . savings = {
total : '0.0292' ,
performance : '0.0297' ,
fee : '0.02' ,
metaMaskFee : '0.0205' ,
medianMetaMaskFee : '0.0202' ,
}
const [
topAggId ,
resultQuotes ,
] = await swapsController . _findTopQuoteAndCalculateSavings ( testInput )
assert . equal ( topAggId , TEST _AGG _ID _1 )
assert . deepStrictEqual ( resultQuotes , expectedResultQuotes )
} )
it ( 'returns the top aggId, without best quote flagged, and quotes with fee values if passed necessary data but no custom convert rate exists' , async function ( ) {
const testInput = mapValues (
getTopQuoteAndSavingsMockQuotes ( ) ,
( quote ) => ( {
... quote ,
destinationToken : '0xnoConversionRateExists' ,
} ) ,
)
const expectedResultQuotes = {
[ TEST _AGG _ID _1 ] : {
... testInput [ TEST _AGG _ID _1 ] ,
ethFee : '0.01' ,
} ,
[ TEST _AGG _ID _2 ] : {
... testInput [ TEST _AGG _ID _2 ] ,
ethFee : '0.02' ,
} ,
[ TEST _AGG _ID _3 ] : {
... testInput [ TEST _AGG _ID _3 ] ,
ethFee : '0.03' ,
} ,
[ TEST _AGG _ID _4 ] : {
... testInput [ TEST _AGG _ID _4 ] ,
ethFee : '0.04' ,
} ,
[ TEST _AGG _ID _5 ] : {
... testInput [ TEST _AGG _ID _5 ] ,
ethFee : '0.05' ,
} ,
[ TEST _AGG _ID _6 ] : {
... testInput [ TEST _AGG _ID _6 ] ,
ethFee : '0.06' ,
} ,
}
const [
topAggId ,
resultQuotes ,
] = await swapsController . _findTopQuoteAndCalculateSavings ( testInput )
assert . equal ( topAggId , TEST _AGG _ID _1 )
assert . deepStrictEqual ( resultQuotes , expectedResultQuotes )
} )
it ( 'returns the top aggId and quotes with savings and fee values if passed necessary data and the source token is ETH' , async function ( ) {
const testInput = mapValues (
getTopQuoteAndSavingsMockQuotes ( ) ,
( quote ) => ( {
... quote ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
} ) ,
)
const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults ( )
const expectedResultQuotes = {
[ TEST _AGG _ID _1 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _1 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '2.0195' ,
} ,
[ TEST _AGG _ID _2 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _2 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.9996' ,
} ,
[ TEST _AGG _ID _3 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _3 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.9698' ,
} ,
[ TEST _AGG _ID _4 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _4 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.94' ,
} ,
[ TEST _AGG _ID _5 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _5 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.9102' ,
} ,
[ TEST _AGG _ID _6 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _6 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.8705' ,
} ,
}
const [
topAggId ,
resultQuotes ,
] = await swapsController . _findTopQuoteAndCalculateSavings ( testInput )
assert . equal ( topAggId , TEST _AGG _ID _1 )
assert . deepStrictEqual ( resultQuotes , expectedResultQuotes )
} )
it ( 'returns the top aggId and quotes with savings and fee values if passed necessary data and the source token is ETH and an ETH fee is included in the trade value of what would be the best quote' , async function ( ) {
const testInput = mapValues (
getTopQuoteAndSavingsMockQuotes ( ) ,
( quote ) => ( {
... quote ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
} ) ,
)
// 0.04 ETH fee included in trade value
testInput [ TEST _AGG _ID _1 ] . trade . value = '0x8b553ece48ec0000'
const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults ( )
const expectedResultQuotes = {
[ TEST _AGG _ID _1 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _1 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8b553ece48ec0000' } ,
overallValueOfQuote : '1.9795' ,
ethFee : '0.05' ,
} ,
[ TEST _AGG _ID _2 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _2 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.9996' ,
isBestQuote : true ,
savings : {
total : '0.0243' ,
performance : '0.0297' ,
fee : '0.015' ,
metaMaskFee : '0.0204' ,
medianMetaMaskFee : '0.0201' ,
} ,
} ,
[ TEST _AGG _ID _3 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _3 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.9698' ,
} ,
[ TEST _AGG _ID _4 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _4 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.94' ,
} ,
[ TEST _AGG _ID _5 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _5 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.9102' ,
} ,
[ TEST _AGG _ID _6 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _6 ] ,
sourceToken : ETH _SWAPS _TOKEN _ADDRESS ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
trade : { value : '0x8ac7230489e80000' } ,
overallValueOfQuote : '1.8705' ,
} ,
}
delete expectedResultQuotes [ TEST _AGG _ID _1 ] . isBestQuote
delete expectedResultQuotes [ TEST _AGG _ID _1 ] . savings
const [
topAggId ,
resultQuotes ,
] = await swapsController . _findTopQuoteAndCalculateSavings ( testInput )
assert . equal ( topAggId , TEST _AGG _ID _2 )
assert . deepStrictEqual ( resultQuotes , expectedResultQuotes )
} )
it ( 'returns the top aggId and quotes with savings and fee values if passed necessary data and the source token is not ETH and an ETH fee is included in the trade value of what would be the best quote' , async function ( ) {
const testInput = getTopQuoteAndSavingsMockQuotes ( )
// 0.04 ETH fee included in trade value
testInput [ TEST _AGG _ID _1 ] . trade . value = '0x8e1bc9bf040000'
const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults ( )
const expectedResultQuotes = {
... baseExpectedResultQuotes ,
[ TEST _AGG _ID _1 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _1 ] ,
trade : { value : '0x8e1bc9bf040000' } ,
overallValueOfQuote : '1.9795' ,
ethFee : '0.05' ,
} ,
[ TEST _AGG _ID _2 ] : {
... baseExpectedResultQuotes [ TEST _AGG _ID _2 ] ,
isBestQuote : true ,
savings : {
total : '0.0243' ,
performance : '0.0297' ,
fee : '0.015' ,
metaMaskFee : '0.0204' ,
medianMetaMaskFee : '0.0201' ,
} ,
} ,
}
delete expectedResultQuotes [ TEST _AGG _ID _1 ] . isBestQuote
delete expectedResultQuotes [ TEST _AGG _ID _1 ] . savings
const [
topAggId ,
resultQuotes ,
] = await swapsController . _findTopQuoteAndCalculateSavings ( testInput )
assert . equal ( topAggId , [ TEST _AGG _ID _2 ] )
assert . deepStrictEqual ( resultQuotes , expectedResultQuotes )
} )
} )
} )
describe ( 'fetchAndSetQuotes' , function ( ) {
describe ( 'fetchAndSetQuotes' , function ( ) {
@ -394,9 +666,15 @@ describe('SwapsController', function () {
gasEstimateWithRefund : 'b8cae' ,
gasEstimateWithRefund : 'b8cae' ,
savings : {
savings : {
fee : '0' ,
fee : '0' ,
metaMaskFee : '0.5050505050505050505' ,
performance : '6' ,
performance : '6' ,
total : '6' ,
total : '5.4949494949494949495' ,
medianMetaMaskFee : '0.44444444444444444444' ,
} ,
} ,
ethFee : '33554432' ,
overallValueOfQuote : '-33554382' ,
metaMaskFeeInEth : '0.5050505050505050505' ,
ethValueOfTokens : '50' ,
} )
} )
assert . strictEqual (
assert . strictEqual (
@ -515,7 +793,7 @@ describe('SwapsController', function () {
MOCK _FETCH _METADATA ,
MOCK _FETCH _METADATA ,
)
)
assert . strictEqual ( newQuotes [ topAggId ] . isBestQuote , false )
assert . strictEqual ( newQuotes [ topAggId ] . isBestQuote , undefined )
} )
} )
} )
} )
@ -865,37 +1143,215 @@ describe('SwapsController', function () {
} )
} )
describe ( 'utils' , function ( ) {
describe ( 'utils' , function ( ) {
describe ( 'getMedian' , function ( ) {
describe ( 'getMedianEthValueQuote ' , function ( ) {
const { getMedian } = utils
const { getMedianEthValueQuote } = utils
it ( 'calculates median correctly with uneven sample' , function ( ) {
it ( 'calculates median correctly with uneven sample' , function ( ) {
const values = [ 3 , 2 , 6 ] . map ( ( value ) => new BigNumber ( value ) )
const expectedResult = {
const median = getMedian ( values )
ethFee : '10' ,
metaMaskFeeInEth : '5' ,
ethValueOfTokens : '0.3' ,
}
const values = [
{
overallValueOfQuote : '3' ,
ethFee : '10' ,
metaMaskFeeInEth : '5' ,
ethValueOfTokens : '0.3' ,
} ,
{
overallValueOfQuote : '2' ,
ethFee : '20' ,
metaMaskFeeInEth : '3' ,
ethValueOfTokens : '0.2' ,
} ,
{
overallValueOfQuote : '6' ,
ethFee : '40' ,
metaMaskFeeInEth : '6' ,
ethValueOfTokens : '0.6' ,
} ,
]
assert . strictEqual (
const median = getMedianEthValueQuote ( values )
median . toNumber ( ) ,
3 ,
assert . deepEqual (
'should have returned correct median' ,
median ,
expectedResult ,
'should have returned correct median quote object' ,
)
)
} )
} )
it ( 'calculates median correctly with even sample' , function ( ) {
it ( 'calculates median correctly with even sample' , function ( ) {
const values = [ 3 , 2 , 2 , 6 ] . map ( ( value ) => new BigNumber ( value ) )
const expectedResult = {
const median = getMedian ( values )
ethFee : '20' ,
metaMaskFeeInEth : '6.5' ,
ethValueOfTokens : '0.25' ,
}
const values = [
{
overallValueOfQuote : '3' ,
ethFee : '10' ,
metaMaskFeeInEth : '5' ,
ethValueOfTokens : '0.3' ,
} ,
{
overallValueOfQuote : '1' ,
ethFee : '20' ,
metaMaskFeeInEth : '3' ,
ethValueOfTokens : '0.2' ,
} ,
{
overallValueOfQuote : '2' ,
ethFee : '30' ,
metaMaskFeeInEth : '8' ,
ethValueOfTokens : '0.2' ,
} ,
{
overallValueOfQuote : '6' ,
ethFee : '40' ,
metaMaskFeeInEth : '6' ,
ethValueOfTokens : '0.6' ,
} ,
]
const median = getMedianEthValueQuote ( values )
assert . strictEqual (
assert . deepEqual (
median . toNumber ( ) ,
median ,
2.5 ,
expectedResult ,
'should have returned correct median' ,
'should have returned correct median quote object' ,
)
} )
it ( 'calculates median correctly with an uneven sample where multiple quotes have the median overall value' , function ( ) {
const expectedResult = {
ethFee : '2' ,
metaMaskFeeInEth : '0.5' ,
ethValueOfTokens : '5' ,
}
const values = [
{
overallValueOfQuote : '1' ,
ethValueOfTokens : '2' ,
ethFee : '1' ,
metaMaskFeeInEth : '0.2' ,
} ,
{
overallValueOfQuote : '3' ,
ethValueOfTokens : '4' ,
ethFee : '1' ,
metaMaskFeeInEth : '0.4' ,
} ,
{
overallValueOfQuote : '3' ,
ethValueOfTokens : '5' ,
ethFee : '2' ,
metaMaskFeeInEth : '0.5' ,
} ,
{
overallValueOfQuote : '3' ,
ethValueOfTokens : '6' ,
ethFee : '3' ,
metaMaskFeeInEth : '0.6' ,
} ,
{
overallValueOfQuote : '4' ,
ethValueOfTokens : '6' ,
ethFee : '2' ,
metaMaskFeeInEth : '0.6' ,
} ,
{
overallValueOfQuote : '4' ,
ethValueOfTokens : '7' ,
ethFee : '3' ,
metaMaskFeeInEth : '0.7' ,
} ,
{
overallValueOfQuote : '6' ,
ethValueOfTokens : '8' ,
ethFee : '2' ,
metaMaskFeeInEth : '0.8' ,
} ,
]
const median = getMedianEthValueQuote ( values )
assert . deepEqual (
median ,
expectedResult ,
'should have returned correct median quote object' ,
)
} )
it ( 'calculates median correctly with an even sample where multiple quotes have the same overall value as either of the two middle values' , function ( ) {
const expectedResult = {
ethFee : '2' ,
metaMaskFeeInEth : '0.55' ,
ethValueOfTokens : '5.5' ,
}
const values = [
{
overallValueOfQuote : '1' ,
ethValueOfTokens : '2' ,
ethFee : '1' ,
metaMaskFeeInEth : '0.2' ,
} ,
{
overallValueOfQuote : '3' ,
ethValueOfTokens : '4' ,
ethFee : '1' ,
metaMaskFeeInEth : '0.4' ,
} ,
{
overallValueOfQuote : '3' ,
ethValueOfTokens : '5' ,
ethFee : '2' ,
metaMaskFeeInEth : '0.5' ,
} ,
{
overallValueOfQuote : '4' ,
ethValueOfTokens : '6' ,
ethFee : '2' ,
metaMaskFeeInEth : '0.6' ,
} ,
{
overallValueOfQuote : '4' ,
ethValueOfTokens : '7' ,
ethFee : '3' ,
metaMaskFeeInEth : '0.7' ,
} ,
{
overallValueOfQuote : '6' ,
ethValueOfTokens : '8' ,
ethFee : '2' ,
metaMaskFeeInEth : '0.8' ,
} ,
]
const median = getMedianEthValueQuote ( values )
assert . deepEqual (
median ,
expectedResult ,
'should have returned correct median quote object' ,
)
)
} )
} )
it ( 'throws on empty or non-array sample' , function ( ) {
it ( 'throws on empty or non-array sample' , function ( ) {
assert . throws ( ( ) => getMedian ( [ ] ) , 'should throw on empty array' )
assert . throws (
( ) => getMedianEthValueQuote ( [ ] ) ,
'should throw on empty array' ,
)
assert . throws ( ( ) => getMedian ( ) , 'should throw on non-array param' )
assert . throws (
( ) => getMedianEthValueQuote ( ) ,
'should throw on non-array param' ,
)
assert . throws ( ( ) => getMedian ( { } ) , 'should throw on non-array param' )
assert . throws (
( ) => getMedianEthValueQuote ( { } ) ,
'should throw on non-array param' ,
)
} )
} )
} )
} )
} )
} )
@ -934,6 +1390,7 @@ function getMockQuotes() {
symbol : 'USDC' ,
symbol : 'USDC' ,
decimals : 18 ,
decimals : 18 ,
} ,
} ,
fee : 1 ,
} ,
} ,
[ TEST _AGG _ID _BEST ] : {
[ TEST _AGG _ID _BEST ] : {
@ -967,6 +1424,7 @@ function getMockQuotes() {
symbol : 'USDC' ,
symbol : 'USDC' ,
decimals : 18 ,
decimals : 18 ,
} ,
} ,
fee : 1 ,
} ,
} ,
[ TEST _AGG _ID _2 ] : {
[ TEST _AGG _ID _2 ] : {
@ -1000,6 +1458,160 @@ function getMockQuotes() {
symbol : 'USDC' ,
symbol : 'USDC' ,
decimals : 18 ,
decimals : 18 ,
} ,
} ,
fee : 1 ,
} ,
}
}
function getTopQuoteAndSavingsMockQuotes ( ) {
// These destination amounts are calculated using the following "pre-fee" amounts
// TEST_AGG_ID_1: 20.5
// TEST_AGG_ID_2: 20.4
// TEST_AGG_ID_3: 20.2
// TEST_AGG_ID_4: 20
// TEST_AGG_ID_5: 19.8
// TEST_AGG_ID_6: 19.5
return {
[ TEST _AGG _ID _1 ] : {
aggregator : TEST _AGG _ID _1 ,
approvalNeeded : null ,
gasEstimate : '0x186a0' ,
destinationAmount : '20295000000000000000' ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
destinationTokenInfo : { decimals : 18 } ,
sourceAmount : '10000000000000000000' ,
sourceToken : '0xsomeERC20TokenAddress' ,
trade : {
value : '0x0' ,
} ,
fee : 1 ,
} ,
[ TEST _AGG _ID _2 ] : {
aggregator : TEST _AGG _ID _2 ,
approvalNeeded : null ,
gasEstimate : '0x30d40' ,
destinationAmount : '20196000000000000000' ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
destinationTokenInfo : { decimals : 18 } ,
sourceAmount : '10000000000000000000' ,
sourceToken : '0xsomeERC20TokenAddress' ,
trade : {
value : '0x0' ,
} ,
fee : 1 ,
} ,
[ TEST _AGG _ID _3 ] : {
aggregator : TEST _AGG _ID _3 ,
approvalNeeded : null ,
gasEstimate : '0x493e0' ,
destinationAmount : '19998000000000000000' ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
destinationTokenInfo : { decimals : 18 } ,
sourceAmount : '10000000000000000000' ,
sourceToken : '0xsomeERC20TokenAddress' ,
trade : {
value : '0x0' ,
} ,
fee : 1 ,
} ,
[ TEST _AGG _ID _4 ] : {
aggregator : TEST _AGG _ID _4 ,
approvalNeeded : null ,
gasEstimate : '0x61a80' ,
destinationAmount : '19800000000000000000' ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
destinationTokenInfo : { decimals : 18 } ,
sourceAmount : '10000000000000000000' ,
sourceToken : '0xsomeERC20TokenAddress' ,
trade : {
value : '0x0' ,
} ,
fee : 1 ,
} ,
[ TEST _AGG _ID _5 ] : {
aggregator : TEST _AGG _ID _5 ,
approvalNeeded : null ,
gasEstimate : '0x7a120' ,
destinationAmount : '19602000000000000000' ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
destinationTokenInfo : { decimals : 18 } ,
sourceAmount : '10000000000000000000' ,
sourceToken : '0xsomeERC20TokenAddress' ,
trade : {
value : '0x0' ,
} ,
fee : 1 ,
} ,
[ TEST _AGG _ID _6 ] : {
aggregator : TEST _AGG _ID _6 ,
approvalNeeded : null ,
gasEstimate : '0x927c0' ,
destinationAmount : '19305000000000000000' ,
destinationToken : '0x1111111111111111111111111111111111111111' ,
destinationTokenInfo : { decimals : 18 } ,
sourceAmount : '10000000000000000000' ,
sourceToken : '0xsomeERC20TokenAddress' ,
trade : {
value : '0x0' ,
} ,
fee : 1 ,
} ,
}
}
function getTopQuoteAndSavingsBaseExpectedResults ( ) {
const baseTestInput = getTopQuoteAndSavingsMockQuotes ( )
return {
[ TEST _AGG _ID _1 ] : {
... baseTestInput [ TEST _AGG _ID _1 ] ,
isBestQuote : true ,
ethFee : '0.01' ,
overallValueOfQuote : '2.0195' ,
metaMaskFeeInEth : '0.0205' ,
ethValueOfTokens : '2.0295' ,
savings : {
total : '0.0441' ,
performance : '0.0396' ,
fee : '0.025' ,
metaMaskFee : '0.0205' ,
medianMetaMaskFee : '0.0201' ,
} ,
} ,
[ TEST _AGG _ID _2 ] : {
... baseTestInput [ TEST _AGG _ID _2 ] ,
ethFee : '0.02' ,
overallValueOfQuote : '1.9996' ,
metaMaskFeeInEth : '0.0204' ,
ethValueOfTokens : '2.0196' ,
} ,
[ TEST _AGG _ID _3 ] : {
... baseTestInput [ TEST _AGG _ID _3 ] ,
ethFee : '0.03' ,
overallValueOfQuote : '1.9698' ,
metaMaskFeeInEth : '0.0202' ,
ethValueOfTokens : '1.9998' ,
} ,
[ TEST _AGG _ID _4 ] : {
... baseTestInput [ TEST _AGG _ID _4 ] ,
ethFee : '0.04' ,
overallValueOfQuote : '1.94' ,
metaMaskFeeInEth : '0.02' ,
ethValueOfTokens : '1.98' ,
} ,
[ TEST _AGG _ID _5 ] : {
... baseTestInput [ TEST _AGG _ID _5 ] ,
ethFee : '0.05' ,
overallValueOfQuote : '1.9102' ,
metaMaskFeeInEth : '0.0198' ,
ethValueOfTokens : '1.9602' ,
} ,
[ TEST _AGG _ID _6 ] : {
... baseTestInput [ TEST _AGG _ID _6 ] ,
ethFee : '0.06' ,
overallValueOfQuote : '1.8705' ,
metaMaskFeeInEth : '0.0195' ,
ethValueOfTokens : '1.9305' ,
} ,
} ,
}
}
}
}