fix: start native orders "samples" at 0 & don't skip neg adj orders (#425)
* fix: start native orders "samples" at 0 & don't skip neg adj orders * fix: bail on routes with invalid output estimation (no valid route) * chore: bump neon-router version * chore: add asset-swapper changelog entry
This commit is contained in:
parent
5f5b951998
commit
eb12eac5f3
@ -1,4 +1,13 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "16.49.7",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Fix native order handling for very small quotes and bump `neon-router` dependency",
|
||||||
|
"pr": 425
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "16.49.6",
|
"version": "16.49.6",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@ -66,7 +66,7 @@
|
|||||||
"@0x/contracts-zero-ex": "^0.30.1",
|
"@0x/contracts-zero-ex": "^0.30.1",
|
||||||
"@0x/dev-utils": "^4.2.9",
|
"@0x/dev-utils": "^4.2.9",
|
||||||
"@0x/json-schemas": "^6.3.0",
|
"@0x/json-schemas": "^6.3.0",
|
||||||
"@0x/neon-router": "^0.3.1",
|
"@0x/neon-router": "^0.3.2",
|
||||||
"@0x/protocol-utils": "^1.10.1",
|
"@0x/protocol-utils": "^1.10.1",
|
||||||
"@0x/quote-server": "^6.0.6",
|
"@0x/quote-server": "^6.0.6",
|
||||||
"@0x/types": "^3.3.4",
|
"@0x/types": "^3.3.4",
|
||||||
|
@ -96,6 +96,7 @@ export function nativeOrdersToFills(
|
|||||||
outputAmountPerEth: BigNumber,
|
outputAmountPerEth: BigNumber,
|
||||||
inputAmountPerEth: BigNumber,
|
inputAmountPerEth: BigNumber,
|
||||||
fees: FeeSchedule,
|
fees: FeeSchedule,
|
||||||
|
filterNegativeAdjustedRateOrders: boolean = true,
|
||||||
): Fill[] {
|
): Fill[] {
|
||||||
const sourcePathId = hexUtils.random();
|
const sourcePathId = hexUtils.random();
|
||||||
// Create a single path from all orders.
|
// Create a single path from all orders.
|
||||||
@ -126,8 +127,8 @@ export function nativeOrdersToFills(
|
|||||||
side === MarketOperation.Sell ? clippedOutput.minus(outputPenalty) : clippedOutput.plus(outputPenalty);
|
side === MarketOperation.Sell ? clippedOutput.minus(outputPenalty) : clippedOutput.plus(outputPenalty);
|
||||||
const adjustedRate =
|
const adjustedRate =
|
||||||
side === MarketOperation.Sell ? adjustedOutput.div(clippedInput) : clippedInput.div(adjustedOutput);
|
side === MarketOperation.Sell ? adjustedOutput.div(clippedInput) : clippedInput.div(adjustedOutput);
|
||||||
// Skip orders with rates that are <= 0.
|
// Optionally skip orders with rates that are <= 0.
|
||||||
if (adjustedRate.lte(0)) {
|
if (filterNegativeAdjustedRateOrders && adjustedRate.lte(0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fills.push({
|
fills.push({
|
||||||
|
@ -5,9 +5,10 @@ import { BigNumber, hexUtils } from '@0x/utils';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { performance } from 'perf_hooks';
|
import { performance } from 'perf_hooks';
|
||||||
|
|
||||||
|
import { DEFAULT_WARNING_LOGGER } from '../../constants';
|
||||||
import { MarketOperation, NativeOrderWithFillableAmounts } from '../../types';
|
import { MarketOperation, NativeOrderWithFillableAmounts } from '../../types';
|
||||||
import { VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID, ZERO_AMOUNT } from '../market_operation_utils/constants';
|
|
||||||
|
|
||||||
|
import { VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID, ZERO_AMOUNT } from './constants';
|
||||||
import { dexSamplesToFills, ethToOutputAmount, nativeOrdersToFills } from './fills';
|
import { dexSamplesToFills, ethToOutputAmount, nativeOrdersToFills } from './fills';
|
||||||
import { DEFAULT_PATH_PENALTY_OPTS, Path, PathPenaltyOpts } from './path';
|
import { DEFAULT_PATH_PENALTY_OPTS, Path, PathPenaltyOpts } from './path';
|
||||||
import { DexSample, ERC20BridgeSource, FeeSchedule, Fill, FillData, SamplerMetrics } from './types';
|
import { DexSample, ERC20BridgeSource, FeeSchedule, Fill, FillData, SamplerMetrics } from './types';
|
||||||
@ -154,8 +155,10 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
const inputs = [];
|
const inputs = [];
|
||||||
const outputs = [];
|
const outputs = [];
|
||||||
const outputFees = [];
|
const outputFees = [];
|
||||||
for (let i = 1; i <= 13; i++) {
|
// NOTE: We start at 0 here because the native order might be much larger than the amount
|
||||||
const fraction = i / 13;
|
// By starting at 0 we make sure we can always use a portion of the native order to fill/partial fill
|
||||||
|
for (let i = 0; i <= 12; i++) {
|
||||||
|
const fraction = i / 12;
|
||||||
const currentInput = BigNumber.min(normalizedOrderInput.times(fraction), normalizedOrderInput);
|
const currentInput = BigNumber.min(normalizedOrderInput.times(fraction), normalizedOrderInput);
|
||||||
const currentOutput = BigNumber.min(normalizedOrderOutput.times(fraction), normalizedOrderOutput);
|
const currentOutput = BigNumber.min(normalizedOrderOutput.times(fraction), normalizedOrderOutput);
|
||||||
const id = `${ERC20BridgeSource.Native}-${serializedPaths.length}-${idx}-${i}`;
|
const id = `${ERC20BridgeSource.Native}-${serializedPaths.length}-${idx}-${i}`;
|
||||||
@ -210,7 +213,11 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
|
|
||||||
const scale = input.dividedBy(totalRoutedAmount);
|
const scale = input.dividedBy(totalRoutedAmount);
|
||||||
for (const [routeInput, routeSamplesAndNativeOrders, outputAmount, sourcePathId] of routesAndSamplesAndOutputs) {
|
for (const [routeInput, routeSamplesAndNativeOrders, outputAmount, sourcePathId] of routesAndSamplesAndOutputs) {
|
||||||
if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount || !Number.isFinite(outputAmount)) {
|
if (!Number.isFinite(outputAmount)) {
|
||||||
|
DEFAULT_WARNING_LOGGER(rustArgs, `neon-router: invalid route outputAmount ${outputAmount}`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64
|
// TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64
|
||||||
@ -229,6 +236,7 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
opts.outputAmountPerEth,
|
opts.outputAmountPerEth,
|
||||||
opts.inputAmountPerEth,
|
opts.inputAmountPerEth,
|
||||||
fees,
|
fees,
|
||||||
|
false,
|
||||||
)[0] as Fill | undefined;
|
)[0] as Fill | undefined;
|
||||||
// Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped
|
// Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped
|
||||||
// and nativeFill will be `undefined`
|
// and nativeFill will be `undefined`
|
||||||
|
@ -959,10 +959,10 @@
|
|||||||
typedoc "~0.16.11"
|
typedoc "~0.16.11"
|
||||||
yargs "^10.0.3"
|
yargs "^10.0.3"
|
||||||
|
|
||||||
"@0x/neon-router@^0.3.1":
|
"@0x/neon-router@^0.3.2":
|
||||||
version "0.3.1"
|
version "0.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.3.1.tgz#4ec13e750d1435357c4928d7f2521a2b4376f27e"
|
resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.3.2.tgz#dc68d0a108060d607b48e3d32ce0ff46f8dc0cc2"
|
||||||
integrity sha512-M4ypTov9KyxsGJpYwobrld3Y2JOlR7U0XjR6BEQE2gQ1k3nie/1wNEI2J4ZjKw++RLDxdv/RCqhgA5VnINzjxA==
|
integrity sha512-AdSPeCxRcjdpmWDkJI1wg+X4q14tmLE21vM0AixtMQQI5+f22sIeUCrPqU9FFKqMQTOW0/3d8tVXzxdollahbA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@mapbox/node-pre-gyp" "^1.0.5"
|
"@mapbox/node-pre-gyp" "^1.0.5"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user