Fix asset-swapper bugs and misc improvements. (#2406)

* `@0x/contracts-erc20-bridge-sampler`: Add gas limits to external quote calls.
`@0x/contract-addresses`: Point `erc20BridgeSampler` to new version.

* `@0x/asset-swapper`: Ignore zero sample results from the sampler contract.
`@0x/asset-swapper`: Allow skipping Uniswap when dealing with low precision amounts with `minUniswapDecimals` option.
`@0x/asset-swapper`: Increase default `runLimit` from `1024` to `4096`.
`@0x/asset-swapper`: Increase default `numSamples` from `8` to `10`
`@0x/asset-swapper`: Fix ordering of optimized orders.
`@0x/asset-swapper`: Fix best and worst quotes being reversed sometimes.
`@0x/asset-swapper`: Fix rounding of quoted asset amounts.

* `@0x/contracts-utils`: Add kovan addresses to `DeploymentConstants`.
`@0x/contract-addresses`: Add kovan `ERC20BridgeSampler` address.

* `@0x/asset-swapper`: Change default `minUniswapDecimals` option from 8 to 7.

* `@0x/contracts-erc20-bridge-sampler`: Fix changelog.

* `@0x/asset-swapper`: Revert uniswap decimals fix.

* `@0x/asset-swapper`: Undo bridge slippage when computing best case quote.

* `@0x/asset-swapper`: Take asset data from input orders instead of output orders in quote result calculation.

* `@0x/asset-swapper`: Move `SAMPLER_CONTRACT_GAS_LIMIT` constant to `market_operation_utils/constants`.

* Compare equivalent asset data

* Fix redundant zero check

* Update CHANGELOG

* Set fee amount in fillable amounts test

Co-authored-by: Jacob Evans <dekz@dekz.net>
This commit is contained in:
Lawrence Forman
2020-01-03 23:21:39 -05:00
committed by GitHub
parent b7b457b076
commit 0571a96cea
18 changed files with 389 additions and 64 deletions

View File

@@ -53,12 +53,12 @@ describe('MarketOperationUtils tests', () => {
expirationTimeSeconds: getRandomInteger(0, 2 ** 64),
makerAssetData: MAKER_ASSET_DATA,
takerAssetData: TAKER_ASSET_DATA,
makerFeeAssetData: assetDataUtils.encodeERC20AssetData(randomAddress()),
takerFeeAssetData: assetDataUtils.encodeERC20AssetData(randomAddress()),
makerFeeAssetData: constants.NULL_BYTES,
takerFeeAssetData: constants.NULL_BYTES,
makerAssetAmount: getRandomInteger(1, 1e18),
takerAssetAmount: getRandomInteger(1, 1e18),
makerFee: getRandomInteger(1, 1e17),
takerFee: getRandomInteger(1, 1e17),
makerFee: constants.ZERO_AMOUNT,
takerFee: constants.ZERO_AMOUNT,
signature: hexUtils.random(),
...overrides,
};
@@ -99,7 +99,7 @@ describe('MarketOperationUtils tests', () => {
const singleTakerAssetAmount = takerAssetAmount.div(rates.length).integerValue(BigNumber.ROUND_UP);
return rates.map(r =>
createOrder({
makerAssetAmount: singleTakerAssetAmount.times(r),
makerAssetAmount: singleTakerAssetAmount.times(r).integerValue(),
takerAssetAmount: singleTakerAssetAmount,
}),
);
@@ -110,7 +110,7 @@ describe('MarketOperationUtils tests', () => {
return (rates as any).map((r: Numberish) =>
createOrder({
makerAssetAmount: singleMakerAssetAmount,
takerAssetAmount: singleMakerAssetAmount.div(r),
takerAssetAmount: singleMakerAssetAmount.div(r).integerValue(),
}),
);
}
@@ -479,22 +479,22 @@ describe('MarketOperationUtils tests', () => {
{ ...DEFAULT_OPTS, numSamples: 4, runLimit: 512, noConflicts: false },
);
expect(improvedOrders).to.be.length(4);
const orderSources = improvedOrders.map(o => getSourceFromAssetData(o.makerAssetData)).sort();
const orderSources = improvedOrders.map(o => getSourceFromAssetData(o.makerAssetData));
const expectedSources = [
ERC20BridgeSource.Native,
ERC20BridgeSource.Uniswap,
ERC20BridgeSource.Eth2Dai,
ERC20BridgeSource.Kyber,
].sort();
ERC20BridgeSource.Eth2Dai,
ERC20BridgeSource.Uniswap,
ERC20BridgeSource.Native,
];
expect(orderSources).to.deep.eq(expectedSources);
});
it('excludes Kyber when `noConflicts` enabled and Uniswap or Eth2Dai are used first', async () => {
const rates: RatesBySource = {};
rates[ERC20BridgeSource.Native] = [0.4, 0.3, 0.2, 0.1];
rates[ERC20BridgeSource.Native] = [0.3, 0.2, 0.1, 0.05];
rates[ERC20BridgeSource.Uniswap] = [0.5, 0.05, 0.05, 0.05];
rates[ERC20BridgeSource.Eth2Dai] = [0.6, 0.05, 0.05, 0.05];
rates[ERC20BridgeSource.Kyber] = [0.7, 0.05, 0.05, 0.05];
rates[ERC20BridgeSource.Kyber] = [0.4, 0.05, 0.05, 0.05];
const marketOperationUtils = new MarketOperationUtils(
createSamplerFromSellRates(rates),
contractAddresses,
@@ -506,19 +506,19 @@ describe('MarketOperationUtils tests', () => {
{ ...DEFAULT_OPTS, numSamples: 4, runLimit: 512, noConflicts: true },
);
expect(improvedOrders).to.be.length(4);
const orderSources = improvedOrders.map(o => getSourceFromAssetData(o.makerAssetData)).sort();
const orderSources = improvedOrders.map(o => getSourceFromAssetData(o.makerAssetData));
const expectedSources = [
ERC20BridgeSource.Native,
ERC20BridgeSource.Native,
ERC20BridgeSource.Uniswap,
ERC20BridgeSource.Eth2Dai,
].sort();
ERC20BridgeSource.Uniswap,
ERC20BridgeSource.Native,
ERC20BridgeSource.Native,
];
expect(orderSources).to.deep.eq(expectedSources);
});
it('excludes Uniswap and Eth2Dai when `noConflicts` enabled and Kyber is used first', async () => {
const rates: RatesBySource = {};
rates[ERC20BridgeSource.Native] = [0.4, 0.3, 0.2, 0.1];
rates[ERC20BridgeSource.Native] = [0.1, 0.05, 0.05, 0.05];
rates[ERC20BridgeSource.Uniswap] = [0.15, 0.05, 0.05, 0.05];
rates[ERC20BridgeSource.Eth2Dai] = [0.15, 0.05, 0.05, 0.05];
rates[ERC20BridgeSource.Kyber] = [0.7, 0.05, 0.05, 0.05];
@@ -533,13 +533,13 @@ describe('MarketOperationUtils tests', () => {
{ ...DEFAULT_OPTS, numSamples: 4, runLimit: 512, noConflicts: true },
);
expect(improvedOrders).to.be.length(4);
const orderSources = improvedOrders.map(o => getSourceFromAssetData(o.makerAssetData)).sort();
const orderSources = improvedOrders.map(o => getSourceFromAssetData(o.makerAssetData));
const expectedSources = [
ERC20BridgeSource.Native,
ERC20BridgeSource.Native,
ERC20BridgeSource.Native,
ERC20BridgeSource.Kyber,
].sort();
ERC20BridgeSource.Native,
ERC20BridgeSource.Native,
ERC20BridgeSource.Native,
];
expect(orderSources).to.deep.eq(expectedSources);
});
});
@@ -729,13 +729,13 @@ describe('MarketOperationUtils tests', () => {
{ ...DEFAULT_OPTS, numSamples: 4, runLimit: 512 },
);
expect(improvedOrders).to.be.length(4);
const orderSources = improvedOrders.map(o => getSourceFromAssetData(o.makerAssetData)).sort();
const orderSources = improvedOrders.map(o => getSourceFromAssetData(o.makerAssetData));
const expectedSources = [
ERC20BridgeSource.Native,
ERC20BridgeSource.Native,
ERC20BridgeSource.Uniswap,
ERC20BridgeSource.Eth2Dai,
].sort();
ERC20BridgeSource.Uniswap,
ERC20BridgeSource.Native,
ERC20BridgeSource.Native,
];
expect(orderSources).to.deep.eq(expectedSources);
});
});