protocol/packages/asset-swapper/test/comparison_price_test.ts
Alex Kroeger 927fe2b58b
Improved ComparisonPrice function (#32)
* separated comparison price function into a new file, accounted for backup orders

* removed scratch code

* Adjusted documentation, object naming

* Refactored comparisonPrice function to use adjusted rate from optimizer, used native order fee schedule to adjust for order fees

* Small fixes to function, added unit tests

* Adjusted fee calculation for comparisonPrice function

* use available OptimalPathRate object

* fix lint error in test, separate out fee calculation

* Fixed market operation utils test, added additional checks for fee schedule

* removed unused dep, prettier
2020-11-18 17:12:35 -08:00

123 lines
4.3 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 { 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 buyMarketSideLiquidity: MarketSideLiquidity = {
// needed params
ethToOutputRate: new BigNumber(500),
ethToInputRate: new BigNumber(1),
side: MarketOperation.Buy,
makerTokenDecimals: 18,
takerTokenDecimals: 18,
// extra
inputAmount: new BigNumber(0),
inputToken: ETH_TOKEN,
outputToken: DAI_TOKEN,
dexQuotes: [dexQuotes],
nativeOrders: [],
orderFillableAmounts: [],
twoHopQuotes: [],
rfqtIndicativeQuotes: [],
quoteSourceFilters: new SourceFilters(),
};
const sellMarketSideLiquidity: MarketSideLiquidity = {
// needed params
ethToOutputRate: new BigNumber(500),
ethToInputRate: new BigNumber(1),
side: MarketOperation.Sell,
makerTokenDecimals: 18,
takerTokenDecimals: 18,
// extra
inputAmount: new BigNumber(0),
inputToken: ETH_TOKEN,
outputToken: DAI_TOKEN,
dexQuotes: [dexQuotes],
nativeOrders: [],
orderFillableAmounts: [],
twoHopQuotes: [],
rfqtIndicativeQuotes: [],
quoteSourceFilters: new SourceFilters(),
};
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);
// expected outcome
const EXPECTED_PRICE = new BigNumber('500.55');
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);
// expected outcome
const EXPECTED_PRICE = new BigNumber('0.0020022024');
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);
expect(comparisonPrices.wholeOrder === undefined);
});
});