154 lines
4.9 KiB
TypeScript
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);
|
|
});
|
|
});
|