protocol/packages/asset-swapper/test/comparison_price_test.ts
2021-06-24 11:58:05 -07:00

154 lines
4.9 KiB
TypeScript

// tslint:disable:custom-no-magic-numbers
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
import 'mocha';
import { SOURCE_FLAGS } from '../src';
import { MarketOperation } from '../src/types';
import { getComparisonPrices } from '../src/utils/market_operation_utils/comparison_price';
import { SourceFilters } from '../src/utils/market_operation_utils/source_filters';
import { DexSample, ERC20BridgeSource, MarketSideLiquidity } from '../src/utils/market_operation_utils/types';
import { chaiSetup } from './utils/chai_setup';
chaiSetup.configure();
const expect = chai.expect;
const DAI_TOKEN = '0x6b175474e89094c44da98b954eedeac495271d0f';
const ETH_TOKEN = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
const GAS_PRICE = new BigNumber(50e9); // 50 gwei
const NATIVE_ORDER_FEE = new BigNumber(220e3); // 220K gas
// DEX samples to fill in MarketSideLiquidity
const kyberSample1: DexSample = {
source: ERC20BridgeSource.Kyber,
input: new BigNumber(10000),
output: new BigNumber(10001),
fillData: {},
};
const uniswapSample1: DexSample = {
source: ERC20BridgeSource.UniswapV2,
input: new BigNumber(10003),
output: new BigNumber(10004),
fillData: {},
};
const dexQuotes: DexSample[] = [kyberSample1, uniswapSample1];
const feeSchedule = {
[ERC20BridgeSource.Native]: _.constant(GAS_PRICE.times(NATIVE_ORDER_FEE)),
};
const exchangeProxyOverhead = (sourceFlags: bigint) => {
if ([SOURCE_FLAGS.RfqOrder].includes(sourceFlags)) {
return new BigNumber(20e3).times(GAS_PRICE);
} else {
return new BigNumber(200e3).times(GAS_PRICE);
}
};
const buyMarketSideLiquidity: MarketSideLiquidity = {
// needed params
outputAmountPerEth: new BigNumber(500),
inputAmountPerEth: new BigNumber(1),
side: MarketOperation.Buy,
makerTokenDecimals: 18,
takerTokenDecimals: 18,
// extra
inputAmount: new BigNumber(0),
inputToken: ETH_TOKEN,
outputToken: DAI_TOKEN,
quotes: {
twoHopQuotes: [],
rfqtIndicativeQuotes: [],
dexQuotes: [dexQuotes],
nativeOrders: [],
},
quoteSourceFilters: new SourceFilters(),
isRfqSupported: false,
};
const sellMarketSideLiquidity: MarketSideLiquidity = {
// needed params
outputAmountPerEth: new BigNumber(500),
inputAmountPerEth: new BigNumber(1),
side: MarketOperation.Sell,
makerTokenDecimals: 18,
takerTokenDecimals: 18,
// extra
inputAmount: new BigNumber(0),
inputToken: ETH_TOKEN,
outputToken: DAI_TOKEN,
quotes: {
dexQuotes: [dexQuotes],
nativeOrders: [],
twoHopQuotes: [],
rfqtIndicativeQuotes: [],
},
quoteSourceFilters: new SourceFilters(),
isRfqSupported: false,
};
describe('getComparisonPrices', async () => {
it('should create a proper comparison price for Sells', () => {
// test selling 10 ETH for DAI
// here, ETH is the input token
// and DAI is the output token
const AMOUNT = new BigNumber(10 * 1e18);
// raw maker over taker rate, let's say is 500 flat
const adjustedRate = new BigNumber(500);
const comparisonPrices = getComparisonPrices(
adjustedRate,
AMOUNT,
sellMarketSideLiquidity,
feeSchedule,
exchangeProxyOverhead,
);
// expected outcome
const EXPECTED_PRICE = new BigNumber('500.6');
expect(comparisonPrices.wholeOrder).to.deep.eq(EXPECTED_PRICE);
});
it('should create a proper comparison price for Buys', () => {
// test buying 10 ETH with DAI
// here, ETH is the input token
// and DAI is the output token (now from the maker's perspective)
const AMOUNT = new BigNumber(10 * 1e18);
// raw maker over taker rate, let's say is ETH/DAI rate is 500 flat
const adjustedRate = new BigNumber(1).dividedBy(new BigNumber(500));
const comparisonPrices = getComparisonPrices(
adjustedRate,
AMOUNT,
buyMarketSideLiquidity,
feeSchedule,
exchangeProxyOverhead,
);
// expected outcome
const EXPECTED_PRICE = new BigNumber('0.0020024029');
expect(comparisonPrices.wholeOrder).to.deep.eq(EXPECTED_PRICE);
});
it('should not return a price if takerAmount is < 0', () => {
// test selling 0.00001 ETH for DAI
// this will result in a negative comparison price, but here we should return undefined
const AMOUNT = new BigNumber(0.00001 * 1e18);
// raw maker over taker rate, let's say is 500 flat
const adjustedRate = new BigNumber(500);
const comparisonPrices = getComparisonPrices(
adjustedRate,
AMOUNT,
sellMarketSideLiquidity,
feeSchedule,
exchangeProxyOverhead,
);
expect(comparisonPrices.wholeOrder === undefined);
});
});