Compare commits
15 Commits
protocol@3
...
protocol@9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a1df67d6b | ||
|
|
4b91411faf | ||
|
|
622a542d57 | ||
|
|
cba53a9a50 | ||
|
|
e186f27f63 | ||
|
|
4cd767ecb8 | ||
|
|
f6e85aedf1 | ||
|
|
b3ee294ba5 | ||
|
|
1c242def93 | ||
|
|
f0fe6f2f69 | ||
|
|
f86d555e49 | ||
|
|
b0f2c40463 | ||
|
|
87be6fbb8a | ||
|
|
9141a9d2c8 | ||
|
|
7f75de347e |
@@ -4,23 +4,28 @@ Audits
|
|||||||
|
|
||||||
Below are links to our third-party audit reports.
|
Below are links to our third-party audit reports.
|
||||||
|
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
| **Release** | **Reports** |
|
| **Release** | **Reports** |
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
| Exchange V4 | * `Consensys Diligence (December 2020) <https://consensys.net/diligence/audits/2020/12/0x-exchange-v4/>`__ |
|
| ERC721OrdersFeature | * `ABDK Consulting <https://s3.us-east-2.amazonaws.com/zeips.0x.org/audits/abdk-consulting/ABDK_0x_Solidity_v_1_0.pdf>`__ |
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
| | |
|
||||||
| Exchange V3 | * `Trail of Bits <http://zeips.0x.org.s3-website.us-east-2.amazonaws.com/audits/56/trail-of-bits/audit.pdf>`_ |
|
| | |
|
||||||
| | * `Consensys Diligence (Exchange) <https://diligence.consensys.net/audits/2019/09/0x-v3-exchange/>`__ |
|
| ERC1155OrdersFeature | |
|
||||||
| | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__ |
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
| Exchange V4 | * `Consensys Diligence (December 2020) <https://consensys.net/diligence/audits/2020/12/0x-exchange-v4/>`__ |
|
||||||
| Exchange V2.1 | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_ |
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
| | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_ |
|
| Exchange V3 | * `Trail of Bits <http://zeips.0x.org.s3-website.us-east-2.amazonaws.com/audits/56/trail-of-bits/audit.pdf>`__ |
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
| | * `Consensys Diligence (Exchange) <https://diligence.consensys.net/audits/2019/09/0x-v3-exchange/>`__ |
|
||||||
| MultiAssetProxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__ |
|
| | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__ |
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
| ERC1155Proxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__ |
|
| Exchange V2.1 | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_ |
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
| | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_ |
|
||||||
| StaticCallProxy | * No third-party audit. |
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
| MultiAssetProxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__ |
|
||||||
| ERC20BridgeProxy | * No third-party audit. |
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
| ERC1155Proxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__ |
|
||||||
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| StaticCallProxy | * No third-party audit. |
|
||||||
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| ERC20BridgeProxy | * No third-party audit. |
|
||||||
|
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|||||||
@@ -1,4 +1,52 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "16.51.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Added `Curve` `YFI-ETH` pool",
|
||||||
|
"pr": 444
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1646888282
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.50.3",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Routing glue optimization",
|
||||||
|
"pr": 439
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Move VIP source routing into neon-router & disable fallback orders for native/plp",
|
||||||
|
"pr": 440
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1646837959
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.50.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Update `Uniswap_V3` address on `Ropsten`",
|
||||||
|
"pr": 441
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1646617024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.50.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add BTRFLY/WETH Curve pool on mainnet",
|
||||||
|
"pr": 437
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Lower Uniswap V3 Sampler gas allowance",
|
||||||
|
"pr": 438
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1646312638
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "16.50.0",
|
"version": "16.50.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
|||||||
@@ -5,6 +5,24 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v16.51.0 - _March 10, 2022_
|
||||||
|
|
||||||
|
* Added `Curve` `YFI-ETH` pool (#444)
|
||||||
|
|
||||||
|
## v16.50.3 - _March 9, 2022_
|
||||||
|
|
||||||
|
* Routing glue optimization (#439)
|
||||||
|
* Move VIP source routing into neon-router & disable fallback orders for native/plp (#440)
|
||||||
|
|
||||||
|
## v16.50.2 - _March 7, 2022_
|
||||||
|
|
||||||
|
* Update `Uniswap_V3` address on `Ropsten` (#441)
|
||||||
|
|
||||||
|
## v16.50.1 - _March 3, 2022_
|
||||||
|
|
||||||
|
* Add BTRFLY/WETH Curve pool on mainnet (#437)
|
||||||
|
* Lower Uniswap V3 Sampler gas allowance (#438)
|
||||||
|
|
||||||
## v16.50.0 - _March 2, 2022_
|
## v16.50.0 - _March 2, 2022_
|
||||||
|
|
||||||
* Adding support for Geist on `Fantom` (#398)
|
* Adding support for Geist on `Fantom` (#398)
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ interface IUniswapV3Pool {
|
|||||||
contract UniswapV3Sampler
|
contract UniswapV3Sampler
|
||||||
{
|
{
|
||||||
/// @dev Gas limit for UniswapV3 calls. This is 100% a guess.
|
/// @dev Gas limit for UniswapV3 calls. This is 100% a guess.
|
||||||
uint256 constant private QUOTE_GAS = 900e3;
|
uint256 constant private QUOTE_GAS = 700e3;
|
||||||
|
|
||||||
/// @dev Sample sell quotes from UniswapV3.
|
/// @dev Sample sell quotes from UniswapV3.
|
||||||
/// @param quoter UniswapV3 Quoter contract.
|
/// @param quoter UniswapV3 Quoter contract.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/asset-swapper",
|
"name": "@0x/asset-swapper",
|
||||||
"version": "16.50.0",
|
"version": "16.51.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
"@0x/contracts-zero-ex": "^0.31.1",
|
"@0x/contracts-zero-ex": "^0.31.1",
|
||||||
"@0x/dev-utils": "^4.2.11",
|
"@0x/dev-utils": "^4.2.11",
|
||||||
"@0x/json-schemas": "^6.4.1",
|
"@0x/json-schemas": "^6.4.1",
|
||||||
"@0x/neon-router": "^0.3.3",
|
"@0x/neon-router": "^0.3.5",
|
||||||
"@0x/protocol-utils": "^1.11.1",
|
"@0x/protocol-utils": "^1.11.1",
|
||||||
"@0x/quote-server": "^6.0.6",
|
"@0x/quote-server": "^6.0.6",
|
||||||
"@0x/types": "^3.3.4",
|
"@0x/types": "^3.3.4",
|
||||||
|
|||||||
@@ -500,6 +500,7 @@ export const MAINNET_TOKENS = {
|
|||||||
OUSD: '0x2a8e1e676ec238d8a992307b495b45b3feaa5e86',
|
OUSD: '0x2a8e1e676ec238d8a992307b495b45b3feaa5e86',
|
||||||
agEUR: '0x1a7e4e63778b4f12a199c062f3efdd288afcbce8',
|
agEUR: '0x1a7e4e63778b4f12a199c062f3efdd288afcbce8',
|
||||||
ibEUR: '0x96e61422b6a9ba0e068b6c5add4ffabc6a4aae27',
|
ibEUR: '0x96e61422b6a9ba0e068b6c5add4ffabc6a4aae27',
|
||||||
|
YFI: '0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BSC_TOKENS = {
|
export const BSC_TOKENS = {
|
||||||
@@ -646,6 +647,7 @@ export const CURVE_POOLS = {
|
|||||||
USDP: '0x42d7025938bec20b69cbae5a77421082407f053a', // usdp
|
USDP: '0x42d7025938bec20b69cbae5a77421082407f053a', // usdp
|
||||||
ib: '0x2dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf', // iron bank
|
ib: '0x2dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf', // iron bank
|
||||||
link: '0xf178c0b5bb7e7abf4e12a4838c7b7c5ba2c623c0', // link
|
link: '0xf178c0b5bb7e7abf4e12a4838c7b7c5ba2c623c0', // link
|
||||||
|
btrflyweth: '0xf43b15ab692fde1f9c24a9fce700adcc809d5391', // redacted cartel
|
||||||
// StableSwap "open pools" (crv.finance)
|
// StableSwap "open pools" (crv.finance)
|
||||||
TUSD: '0xecd5e75afb02efa118af914515d6521aabd189f1',
|
TUSD: '0xecd5e75afb02efa118af914515d6521aabd189f1',
|
||||||
STABLEx: '0x3252efd4ea2d6c78091a1f43982ee2c3659cc3d1',
|
STABLEx: '0x3252efd4ea2d6c78091a1f43982ee2c3659cc3d1',
|
||||||
@@ -668,6 +670,7 @@ export const CURVE_POOLS = {
|
|||||||
d3pool: '0xbaaa1f5dba42c3389bdbc2c9d2de134f5cd0dc89',
|
d3pool: '0xbaaa1f5dba42c3389bdbc2c9d2de134f5cd0dc89',
|
||||||
triEURpool: '0xb9446c4ef5ebe66268da6700d26f96273de3d571',
|
triEURpool: '0xb9446c4ef5ebe66268da6700d26f96273de3d571',
|
||||||
ibEURsEUR: '0x19b080fe1ffa0553469d20ca36219f17fcf03859',
|
ibEURsEUR: '0x19b080fe1ffa0553469d20ca36219f17fcf03859',
|
||||||
|
wethyfi: '0xc26b89a667578ec7b3f11b2f98d6fd15c07c54ba',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_POOLS = {
|
export const CURVE_V2_POOLS = {
|
||||||
@@ -1019,6 +1022,16 @@ const createCurveV2MetaTriPool = (info: { tokens: string[]; pool: string; gasSch
|
|||||||
gasSchedule: info.gasSchedule,
|
gasSchedule: info.gasSchedule,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const createCurveFactoryCryptoExchangePool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_uint256,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_uint256,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
tokens: info.tokens,
|
||||||
|
metaTokens: undefined,
|
||||||
|
poolAddress: info.pool,
|
||||||
|
gasSchedule: info.gasSchedule,
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mainnet Curve configuration
|
* Mainnet Curve configuration
|
||||||
* The tokens are in order of their index, which each curve defines
|
* The tokens are in order of their index, which each curve defines
|
||||||
@@ -1285,6 +1298,16 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
pool: CURVE_POOLS.ibEURsEUR,
|
pool: CURVE_POOLS.ibEURsEUR,
|
||||||
gasSchedule: 176e3,
|
gasSchedule: 176e3,
|
||||||
}),
|
}),
|
||||||
|
[CURVE_POOLS.btrflyweth]: createCurveFactoryCryptoExchangePool({
|
||||||
|
tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.BTRFLY],
|
||||||
|
pool: CURVE_POOLS.btrflyweth,
|
||||||
|
gasSchedule: 250e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.wethyfi]: createCurveFactoryCryptoExchangePool({
|
||||||
|
tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.YFI],
|
||||||
|
pool: CURVE_POOLS.wethyfi,
|
||||||
|
gasSchedule: 250e3,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
export const CURVE_V2_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
||||||
@@ -2072,7 +2095,7 @@ export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
|
|||||||
},
|
},
|
||||||
[ChainId.Ropsten]: {
|
[ChainId.Ropsten]: {
|
||||||
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
|
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
|
||||||
router: '0x03782388516e94fcd4c18666303601a12aa729ea',
|
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
|
||||||
},
|
},
|
||||||
[ChainId.Polygon]: {
|
[ChainId.Polygon]: {
|
||||||
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
|
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
|
||||||
|
|||||||
@@ -175,9 +175,9 @@ export function dexSamplesToFills(
|
|||||||
const { source, fillData } = sample;
|
const { source, fillData } = sample;
|
||||||
const input = sample.input.minus(prevSample ? prevSample.input : 0);
|
const input = sample.input.minus(prevSample ? prevSample.input : 0);
|
||||||
const output = sample.output.minus(prevSample ? prevSample.output : 0);
|
const output = sample.output.minus(prevSample ? prevSample.output : 0);
|
||||||
const fee = fees[source] === undefined ? 0 : fees[source]!(sample.fillData) || 0;
|
|
||||||
let penalty = ZERO_AMOUNT;
|
let penalty = ZERO_AMOUNT;
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
|
const fee = fees[source] === undefined ? 0 : fees[source]!(sample.fillData) || 0;
|
||||||
// Only the first fill in a DEX path incurs a penalty.
|
// Only the first fill in a DEX path incurs a penalty.
|
||||||
penalty = ethToOutputAmount({
|
penalty = ethToOutputAmount({
|
||||||
input,
|
input,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import { createFills } from './fills';
|
|||||||
import { getBestTwoHopQuote } from './multihop_utils';
|
import { getBestTwoHopQuote } from './multihop_utils';
|
||||||
import { createOrdersFromTwoHopSample } from './orders';
|
import { createOrdersFromTwoHopSample } from './orders';
|
||||||
import { Path, PathPenaltyOpts } from './path';
|
import { Path, PathPenaltyOpts } from './path';
|
||||||
import { fillsToSortedPaths, findOptimalPathJSAsync, findOptimalRustPathFromSamples } from './path_optimizer';
|
import { findOptimalPathJSAsync, findOptimalRustPathFromSamples } from './path_optimizer';
|
||||||
import { DexOrderSampler, getSampleAmounts } from './sampler';
|
import { DexOrderSampler, getSampleAmounts } from './sampler';
|
||||||
import { SourceFilters } from './source_filters';
|
import { SourceFilters } from './source_filters';
|
||||||
import {
|
import {
|
||||||
@@ -493,18 +493,6 @@ export class MarketOperationUtils {
|
|||||||
} as NativeOrderWithFillableAmounts),
|
} as NativeOrderWithFillableAmounts),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Convert native orders and dex quotes into `Fill` objects.
|
|
||||||
const fills = createFills({
|
|
||||||
side,
|
|
||||||
orders: [...nativeOrders, ...augmentedRfqtIndicativeQuotes],
|
|
||||||
dexQuotes,
|
|
||||||
targetInput: inputAmount,
|
|
||||||
outputAmountPerEth,
|
|
||||||
inputAmountPerEth,
|
|
||||||
excludedSources: opts.excludedSources,
|
|
||||||
feeSchedule: opts.feeSchedule,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Find the optimal path.
|
// Find the optimal path.
|
||||||
const penaltyOpts: PathPenaltyOpts = {
|
const penaltyOpts: PathPenaltyOpts = {
|
||||||
outputAmountPerEth,
|
outputAmountPerEth,
|
||||||
@@ -517,13 +505,11 @@ export class MarketOperationUtils {
|
|||||||
const takerAmountPerEth = side === MarketOperation.Sell ? inputAmountPerEth : outputAmountPerEth;
|
const takerAmountPerEth = side === MarketOperation.Sell ? inputAmountPerEth : outputAmountPerEth;
|
||||||
const makerAmountPerEth = side === MarketOperation.Sell ? outputAmountPerEth : inputAmountPerEth;
|
const makerAmountPerEth = side === MarketOperation.Sell ? outputAmountPerEth : inputAmountPerEth;
|
||||||
|
|
||||||
// Find the unoptimized best rate to calculate savings from optimizer
|
let fills: Fill[][];
|
||||||
const _unoptimizedPath = fillsToSortedPaths(fills, side, inputAmount, penaltyOpts)[0];
|
|
||||||
const unoptimizedPath = _unoptimizedPath ? _unoptimizedPath.collapse(orderOpts) : undefined;
|
|
||||||
|
|
||||||
// Find the optimal path using Rust router if enabled, otherwise fallback to JS Router
|
// Find the optimal path using Rust router if enabled, otherwise fallback to JS Router
|
||||||
let optimalPath: Path | undefined;
|
let optimalPath: Path | undefined;
|
||||||
if (SHOULD_USE_RUST_ROUTER) {
|
if (SHOULD_USE_RUST_ROUTER) {
|
||||||
|
fills = [[]];
|
||||||
optimalPath = findOptimalRustPathFromSamples(
|
optimalPath = findOptimalRustPathFromSamples(
|
||||||
side,
|
side,
|
||||||
dexQuotes,
|
dexQuotes,
|
||||||
@@ -536,6 +522,18 @@ export class MarketOperationUtils {
|
|||||||
opts.samplerMetrics,
|
opts.samplerMetrics,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// Convert native orders and dex quotes into `Fill` objects.
|
||||||
|
fills = createFills({
|
||||||
|
side,
|
||||||
|
orders: [...nativeOrders, ...augmentedRfqtIndicativeQuotes],
|
||||||
|
dexQuotes,
|
||||||
|
targetInput: inputAmount,
|
||||||
|
outputAmountPerEth,
|
||||||
|
inputAmountPerEth,
|
||||||
|
excludedSources: opts.excludedSources,
|
||||||
|
feeSchedule: opts.feeSchedule,
|
||||||
|
});
|
||||||
|
|
||||||
optimalPath = await findOptimalPathJSAsync(
|
optimalPath = await findOptimalPathJSAsync(
|
||||||
side,
|
side,
|
||||||
fills,
|
fills,
|
||||||
@@ -561,7 +559,6 @@ export class MarketOperationUtils {
|
|||||||
sourceFlags: SOURCE_FLAGS[ERC20BridgeSource.MultiHop],
|
sourceFlags: SOURCE_FLAGS[ERC20BridgeSource.MultiHop],
|
||||||
marketSideLiquidity,
|
marketSideLiquidity,
|
||||||
adjustedRate: bestTwoHopRate,
|
adjustedRate: bestTwoHopRate,
|
||||||
unoptimizedPath,
|
|
||||||
takerAmountPerEth,
|
takerAmountPerEth,
|
||||||
makerAmountPerEth,
|
makerAmountPerEth,
|
||||||
};
|
};
|
||||||
@@ -573,7 +570,10 @@ export class MarketOperationUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a fallback path if required
|
// Generate a fallback path if required
|
||||||
await this._addOptionalFallbackAsync(side, inputAmount, optimalPath, dexQuotes, fills, opts, penaltyOpts);
|
// TODO(kimpers): Will experiment with disabling this and see how it affects revert rate
|
||||||
|
// to avoid yet another router roundtrip
|
||||||
|
// TODO: clean this up if we don't need it
|
||||||
|
// await this._addOptionalFallbackAsync(side, inputAmount, optimalPath, dexQuotes, fills, opts, penaltyOpts);
|
||||||
const collapsedPath = optimalPath.collapse(orderOpts);
|
const collapsedPath = optimalPath.collapse(orderOpts);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -582,7 +582,6 @@ export class MarketOperationUtils {
|
|||||||
sourceFlags: collapsedPath.sourceFlags,
|
sourceFlags: collapsedPath.sourceFlags,
|
||||||
marketSideLiquidity,
|
marketSideLiquidity,
|
||||||
adjustedRate: optimalPathRate,
|
adjustedRate: optimalPathRate,
|
||||||
unoptimizedPath,
|
|
||||||
takerAmountPerEth,
|
takerAmountPerEth,
|
||||||
makerAmountPerEth,
|
makerAmountPerEth,
|
||||||
};
|
};
|
||||||
@@ -778,6 +777,8 @@ export class MarketOperationUtils {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO(kimpers): Remove this when we know that it's safe to drop the fallbacks on native orders
|
||||||
// tslint:disable-next-line: prefer-function-over-method
|
// tslint:disable-next-line: prefer-function-over-method
|
||||||
private async _addOptionalFallbackAsync(
|
private async _addOptionalFallbackAsync(
|
||||||
side: MarketOperation,
|
side: MarketOperation,
|
||||||
@@ -843,6 +844,7 @@ export class MarketOperationUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// tslint:disable: max-file-line-count
|
// tslint:disable: max-file-line-count
|
||||||
|
|||||||
@@ -122,17 +122,8 @@ export class Path {
|
|||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// If there are contiguous bridge orders, we can batch them together.
|
|
||||||
// TODO jacob pretty sure this is from DFB and we can remove
|
|
||||||
const contiguousBridgeFills = [collapsedFills[i]];
|
|
||||||
for (let j = i + 1; j < collapsedFills.length; ++j) {
|
|
||||||
if (collapsedFills[j].source === ERC20BridgeSource.Native) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
contiguousBridgeFills.push(collapsedFills[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.orders.push(createBridgeOrder(contiguousBridgeFills[0], makerToken, takerToken, opts.side));
|
this.orders.push(createBridgeOrder(collapsedFills[i], makerToken, takerToken, opts.side));
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
return this as CollapsedPath;
|
return this as CollapsedPath;
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
opts: PathPenaltyOpts,
|
opts: PathPenaltyOpts,
|
||||||
fees: FeeSchedule,
|
fees: FeeSchedule,
|
||||||
neonRouterNumSamples: number,
|
neonRouterNumSamples: number,
|
||||||
): Path | undefined {
|
vipSourcesSet: Set<ERC20BridgeSource>,
|
||||||
|
): { allSourcesPath: Path | undefined; vipSourcesPath: Path | undefined } | undefined {
|
||||||
// Currently the rust router is unable to handle 1 base unit sized quotes and will error out
|
// Currently the rust router is unable to handle 1 base unit sized quotes and will error out
|
||||||
// To avoid flooding the logs with these errors we just return an insufficient liquidity error
|
// To avoid flooding the logs with these errors we just return an insufficient liquidity error
|
||||||
// which is how the JS router handles these quotes today
|
// which is how the JS router handles these quotes today
|
||||||
@@ -94,6 +95,127 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
return fills[0];
|
return fills[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createPathFromStrategy = (sourcesRustRoute: Float64Array, sourcesOutputAmounts: Float64Array) => {
|
||||||
|
const routesAndSamplesAndOutputs = _.zip(
|
||||||
|
sourcesRustRoute,
|
||||||
|
samplesAndNativeOrdersWithResults,
|
||||||
|
sourcesOutputAmounts,
|
||||||
|
sampleSourcePathIds,
|
||||||
|
);
|
||||||
|
const adjustedFills: Fill[] = [];
|
||||||
|
const totalRoutedAmount = BigNumber.sum(...sourcesRustRoute);
|
||||||
|
|
||||||
|
const scale = input.dividedBy(totalRoutedAmount);
|
||||||
|
for (const [
|
||||||
|
routeInput,
|
||||||
|
routeSamplesAndNativeOrders,
|
||||||
|
outputAmount,
|
||||||
|
sourcePathId,
|
||||||
|
] of routesAndSamplesAndOutputs) {
|
||||||
|
if (!Number.isFinite(outputAmount)) {
|
||||||
|
DEFAULT_WARNING_LOGGER(rustArgs, `neon-router: invalid route outputAmount ${outputAmount}`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64
|
||||||
|
// we can work around it by scaling it and rounding up. However now we end up with a total amount of a couple base units too much
|
||||||
|
const rustInputAdjusted = BigNumber.min(
|
||||||
|
new BigNumber(routeInput).multipliedBy(scale).integerValue(BigNumber.ROUND_CEIL),
|
||||||
|
input,
|
||||||
|
);
|
||||||
|
|
||||||
|
const current = routeSamplesAndNativeOrders[routeSamplesAndNativeOrders.length - 1];
|
||||||
|
if (!isDexSample(current)) {
|
||||||
|
const nativeFill = nativeOrdersToFills(
|
||||||
|
side,
|
||||||
|
[current],
|
||||||
|
rustInputAdjusted,
|
||||||
|
opts.outputAmountPerEth,
|
||||||
|
opts.inputAmountPerEth,
|
||||||
|
fees,
|
||||||
|
false,
|
||||||
|
)[0] as Fill | undefined;
|
||||||
|
// Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped
|
||||||
|
// and nativeFill will be `undefined`
|
||||||
|
if (nativeFill) {
|
||||||
|
// NOTE: For Limit/RFQ orders we are done here. No need to scale output
|
||||||
|
adjustedFills.push({ ...nativeFill, sourcePathId: sourcePathId ?? hexUtils.random() });
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: For DexSamples only
|
||||||
|
let fill = createFill(current);
|
||||||
|
if (!fill) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const routeSamples = routeSamplesAndNativeOrders as Array<DexSample<FillData>>;
|
||||||
|
// Descend to approach a closer fill for fillData which may not be consistent
|
||||||
|
// throughout the path (UniswapV3) and for a closer guesstimate at
|
||||||
|
// gas used
|
||||||
|
|
||||||
|
assert.assert(routeSamples.length >= 1, 'Found no sample to use for source');
|
||||||
|
for (let k = routeSamples.length - 1; k >= 0; k--) {
|
||||||
|
if (k === 0) {
|
||||||
|
fill = createFill(routeSamples[0]) ?? fill;
|
||||||
|
}
|
||||||
|
if (rustInputAdjusted.isGreaterThan(routeSamples[k].input)) {
|
||||||
|
const left = routeSamples[k];
|
||||||
|
const right = routeSamples[k + 1];
|
||||||
|
if (left && right) {
|
||||||
|
fill =
|
||||||
|
createFill({
|
||||||
|
...right, // default to the greater (for gas used)
|
||||||
|
input: rustInputAdjusted,
|
||||||
|
output: new BigNumber(outputAmount),
|
||||||
|
}) ?? fill;
|
||||||
|
} else {
|
||||||
|
assert.assert(Boolean(left || right), 'No valid sample to use');
|
||||||
|
fill = createFill(left || right) ?? fill;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(kimpers): remove once we have solved the rounding/precision loss issues in the Rust router
|
||||||
|
const maxSampledOutput = BigNumber.max(...routeSamples.map(s => s.output));
|
||||||
|
// Scale output by scale factor but never go above the largest sample in sell quotes (unknown liquidity) or below 1 base unit (unfillable)
|
||||||
|
const scaleOutput = (output: BigNumber) => {
|
||||||
|
// Don't try to scale 0 output as it will be clamped to 1
|
||||||
|
if (output.eq(ZERO_AMOUNT)) {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scaled = output
|
||||||
|
.times(scale)
|
||||||
|
.decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL);
|
||||||
|
const capped = MarketOperation.Sell ? BigNumber.min(scaled, maxSampledOutput) : scaled;
|
||||||
|
|
||||||
|
return BigNumber.max(capped, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
adjustedFills.push({
|
||||||
|
...fill,
|
||||||
|
input: rustInputAdjusted,
|
||||||
|
output: scaleOutput(fill.output),
|
||||||
|
adjustedOutput: scaleOutput(fill.adjustedOutput),
|
||||||
|
index: 0,
|
||||||
|
parent: undefined,
|
||||||
|
sourcePathId: sourcePathId ?? hexUtils.random(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adjustedFills.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathFromRustInputs = Path.create(side, adjustedFills, input, opts);
|
||||||
|
|
||||||
|
return pathFromRustInputs;
|
||||||
|
};
|
||||||
|
|
||||||
const samplesAndNativeOrdersWithResults: Array<DexSample[] | NativeOrderWithFillableAmounts[]> = [];
|
const samplesAndNativeOrdersWithResults: Array<DexSample[] | NativeOrderWithFillableAmounts[]> = [];
|
||||||
const serializedPaths: SerializedPath[] = [];
|
const serializedPaths: SerializedPath[] = [];
|
||||||
const sampleSourcePathIds: string[] = [];
|
const sampleSourcePathIds: string[] = [];
|
||||||
@@ -136,6 +258,7 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: [],
|
outputs: [],
|
||||||
outputFees: [],
|
outputFees: [],
|
||||||
|
isVip: vipSourcesSet.has(singleSourceSamplesWithOutput[0]?.source),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -194,6 +317,7 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
inputs,
|
inputs,
|
||||||
outputs,
|
outputs,
|
||||||
outputFees,
|
outputFees,
|
||||||
|
isVip: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
samplesAndNativeOrdersWithResults.push([nativeOrder]);
|
samplesAndNativeOrdersWithResults.push([nativeOrder]);
|
||||||
@@ -212,129 +336,42 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const allSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length);
|
const allSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length);
|
||||||
const strategySourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length);
|
const allSourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length);
|
||||||
route(rustArgs, allSourcesRustRoute, strategySourcesOutputAmounts, neonRouterNumSamples);
|
const vipSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length);
|
||||||
|
const vipSourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length);
|
||||||
|
|
||||||
|
route(
|
||||||
|
rustArgs,
|
||||||
|
allSourcesRustRoute,
|
||||||
|
allSourcesOutputAmounts,
|
||||||
|
vipSourcesRustRoute,
|
||||||
|
vipSourcesOutputAmounts,
|
||||||
|
neonRouterNumSamples,
|
||||||
|
);
|
||||||
assert.assert(
|
assert.assert(
|
||||||
rustArgs.pathsIn.length === allSourcesRustRoute.length,
|
rustArgs.pathsIn.length === allSourcesRustRoute.length,
|
||||||
'different number of sources in the Router output than the input',
|
'different number of sources in the Router output than the input',
|
||||||
);
|
);
|
||||||
assert.assert(
|
assert.assert(
|
||||||
rustArgs.pathsIn.length === strategySourcesOutputAmounts.length,
|
rustArgs.pathsIn.length === allSourcesOutputAmounts.length,
|
||||||
|
'different number of sources in the Router output amounts results than the input',
|
||||||
|
);
|
||||||
|
assert.assert(
|
||||||
|
rustArgs.pathsIn.length === vipSourcesRustRoute.length,
|
||||||
|
'different number of sources in the Router output than the input',
|
||||||
|
);
|
||||||
|
assert.assert(
|
||||||
|
rustArgs.pathsIn.length === vipSourcesOutputAmounts.length,
|
||||||
'different number of sources in the Router output amounts results than the input',
|
'different number of sources in the Router output amounts results than the input',
|
||||||
);
|
);
|
||||||
|
|
||||||
const routesAndSamplesAndOutputs = _.zip(
|
const allSourcesPath = createPathFromStrategy(allSourcesRustRoute, allSourcesOutputAmounts);
|
||||||
allSourcesRustRoute,
|
const vipSourcesPath = createPathFromStrategy(vipSourcesRustRoute, vipSourcesOutputAmounts);
|
||||||
samplesAndNativeOrdersWithResults,
|
|
||||||
strategySourcesOutputAmounts,
|
|
||||||
sampleSourcePathIds,
|
|
||||||
);
|
|
||||||
const adjustedFills: Fill[] = [];
|
|
||||||
const totalRoutedAmount = BigNumber.sum(...allSourcesRustRoute);
|
|
||||||
|
|
||||||
const scale = input.dividedBy(totalRoutedAmount);
|
return {
|
||||||
for (const [routeInput, routeSamplesAndNativeOrders, outputAmount, sourcePathId] of routesAndSamplesAndOutputs) {
|
allSourcesPath,
|
||||||
if (!Number.isFinite(outputAmount)) {
|
vipSourcesPath,
|
||||||
DEFAULT_WARNING_LOGGER(rustArgs, `neon-router: invalid route outputAmount ${outputAmount}`);
|
};
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64
|
|
||||||
// we can work around it by scaling it and rounding up. However now we end up with a total amount of a couple base units too much
|
|
||||||
const rustInputAdjusted = BigNumber.min(
|
|
||||||
new BigNumber(routeInput).multipliedBy(scale).integerValue(BigNumber.ROUND_CEIL),
|
|
||||||
input,
|
|
||||||
);
|
|
||||||
|
|
||||||
const current = routeSamplesAndNativeOrders[routeSamplesAndNativeOrders.length - 1];
|
|
||||||
if (!isDexSample(current)) {
|
|
||||||
const nativeFill = nativeOrdersToFills(
|
|
||||||
side,
|
|
||||||
[current],
|
|
||||||
rustInputAdjusted,
|
|
||||||
opts.outputAmountPerEth,
|
|
||||||
opts.inputAmountPerEth,
|
|
||||||
fees,
|
|
||||||
false,
|
|
||||||
)[0] as Fill | undefined;
|
|
||||||
// Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped
|
|
||||||
// and nativeFill will be `undefined`
|
|
||||||
if (nativeFill) {
|
|
||||||
// NOTE: For Limit/RFQ orders we are done here. No need to scale output
|
|
||||||
adjustedFills.push({ ...nativeFill, sourcePathId: sourcePathId ?? hexUtils.random() });
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: For DexSamples only
|
|
||||||
let fill = createFill(current);
|
|
||||||
if (!fill) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const routeSamples = routeSamplesAndNativeOrders as Array<DexSample<FillData>>;
|
|
||||||
// Descend to approach a closer fill for fillData which may not be consistent
|
|
||||||
// throughout the path (UniswapV3) and for a closer guesstimate at
|
|
||||||
// gas used
|
|
||||||
|
|
||||||
assert.assert(routeSamples.length >= 1, 'Found no sample to use for source');
|
|
||||||
for (let k = routeSamples.length - 1; k >= 0; k--) {
|
|
||||||
if (k === 0) {
|
|
||||||
fill = createFill(routeSamples[0]) ?? fill;
|
|
||||||
}
|
|
||||||
if (rustInputAdjusted.isGreaterThan(routeSamples[k].input)) {
|
|
||||||
const left = routeSamples[k];
|
|
||||||
const right = routeSamples[k + 1];
|
|
||||||
if (left && right) {
|
|
||||||
fill =
|
|
||||||
createFill({
|
|
||||||
...right, // default to the greater (for gas used)
|
|
||||||
input: rustInputAdjusted,
|
|
||||||
output: new BigNumber(outputAmount),
|
|
||||||
}) ?? fill;
|
|
||||||
} else {
|
|
||||||
assert.assert(Boolean(left || right), 'No valid sample to use');
|
|
||||||
fill = createFill(left || right) ?? fill;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(kimpers): remove once we have solved the rounding/precision loss issues in the Rust router
|
|
||||||
const maxSampledOutput = BigNumber.max(...routeSamples.map(s => s.output));
|
|
||||||
// Scale output by scale factor but never go above the largest sample (unknown liquidity) or below 1 base unit (unfillable)
|
|
||||||
const scaleOutput = (output: BigNumber) => {
|
|
||||||
// Don't try to scale 0 output as it will be clamped to 1
|
|
||||||
if (output.eq(ZERO_AMOUNT)) {
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scaled = output
|
|
||||||
.times(scale)
|
|
||||||
.decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL);
|
|
||||||
|
|
||||||
return BigNumber.max(BigNumber.min(scaled, maxSampledOutput), 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
adjustedFills.push({
|
|
||||||
...fill,
|
|
||||||
input: rustInputAdjusted,
|
|
||||||
output: scaleOutput(fill.output),
|
|
||||||
adjustedOutput: scaleOutput(fill.adjustedOutput),
|
|
||||||
index: 0,
|
|
||||||
parent: undefined,
|
|
||||||
sourcePathId: sourcePathId ?? hexUtils.random(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (adjustedFills.length === 0) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pathFromRustInputs = Path.create(side, adjustedFills, input, opts);
|
|
||||||
|
|
||||||
return pathFromRustInputs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findOptimalRustPathFromSamples(
|
export function findOptimalRustPathFromSamples(
|
||||||
@@ -348,9 +385,18 @@ export function findOptimalRustPathFromSamples(
|
|||||||
neonRouterNumSamples: number,
|
neonRouterNumSamples: number,
|
||||||
samplerMetrics?: SamplerMetrics,
|
samplerMetrics?: SamplerMetrics,
|
||||||
): Path | undefined {
|
): Path | undefined {
|
||||||
const beforeAllTimeMs = performance.now();
|
const beforeTimeMs = performance.now();
|
||||||
let beforeTimeMs = performance.now();
|
const sendMetrics = () => {
|
||||||
const allSourcesPath = findRoutesAndCreateOptimalPath(
|
// tslint:disable-next-line: no-unused-expression
|
||||||
|
samplerMetrics &&
|
||||||
|
samplerMetrics.logRouterDetails({
|
||||||
|
router: 'neon-router',
|
||||||
|
type: 'total',
|
||||||
|
timingMs: performance.now() - beforeTimeMs,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const vipSourcesSet = new Set(VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID[chainId]);
|
||||||
|
const paths = findRoutesAndCreateOptimalPath(
|
||||||
side,
|
side,
|
||||||
samples,
|
samples,
|
||||||
nativeOrders,
|
nativeOrders,
|
||||||
@@ -358,58 +404,22 @@ export function findOptimalRustPathFromSamples(
|
|||||||
opts,
|
opts,
|
||||||
fees,
|
fees,
|
||||||
neonRouterNumSamples,
|
neonRouterNumSamples,
|
||||||
|
vipSourcesSet,
|
||||||
);
|
);
|
||||||
// tslint:disable-next-line: no-unused-expression
|
|
||||||
samplerMetrics &&
|
if (!paths) {
|
||||||
samplerMetrics.logRouterDetails({
|
sendMetrics();
|
||||||
router: 'neon-router',
|
|
||||||
type: 'all',
|
|
||||||
timingMs: performance.now() - beforeTimeMs,
|
|
||||||
});
|
|
||||||
if (!allSourcesPath) {
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vipSources = VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID[chainId];
|
const { allSourcesPath, vipSourcesPath } = paths;
|
||||||
|
|
||||||
// HACK(kimpers): The Rust router currently doesn't account for VIP sources correctly
|
if (!allSourcesPath || vipSourcesPath?.isBetterThan(allSourcesPath)) {
|
||||||
// we need to try to route them in isolation and compare with the results all sources
|
sendMetrics();
|
||||||
if (vipSources.length > 0) {
|
return vipSourcesPath;
|
||||||
beforeTimeMs = performance.now();
|
|
||||||
const vipSourcesSet = new Set(vipSources);
|
|
||||||
const vipSourcesSamples = samples.filter(s => s[0] && vipSourcesSet.has(s[0].source));
|
|
||||||
|
|
||||||
if (vipSourcesSamples.length > 0) {
|
|
||||||
const vipSourcesPath = findRoutesAndCreateOptimalPath(
|
|
||||||
side,
|
|
||||||
vipSourcesSamples,
|
|
||||||
[],
|
|
||||||
input,
|
|
||||||
opts,
|
|
||||||
fees,
|
|
||||||
neonRouterNumSamples,
|
|
||||||
);
|
|
||||||
// tslint:disable-next-line: no-unused-expression
|
|
||||||
samplerMetrics &&
|
|
||||||
samplerMetrics.logRouterDetails({
|
|
||||||
router: 'neon-router',
|
|
||||||
type: 'vip',
|
|
||||||
timingMs: performance.now() - beforeTimeMs,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (vipSourcesPath?.isBetterThan(allSourcesPath)) {
|
|
||||||
return vipSourcesPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// tslint:disable-next-line: no-unused-expression
|
|
||||||
samplerMetrics &&
|
|
||||||
samplerMetrics.logRouterDetails({
|
|
||||||
router: 'neon-router',
|
|
||||||
type: 'total',
|
|
||||||
timingMs: performance.now() - beforeAllTimeMs,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
sendMetrics();
|
||||||
return allSourcesPath;
|
return allSourcesPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { NativeOrderWithFillableAmounts, RfqFirmQuoteValidator, RfqRequestOpts }
|
|||||||
import { QuoteRequestor, V4RFQIndicativeQuoteMM } from '../../utils/quote_requestor';
|
import { QuoteRequestor, V4RFQIndicativeQuoteMM } from '../../utils/quote_requestor';
|
||||||
import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from '../quote_report_generator';
|
import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from '../quote_report_generator';
|
||||||
|
|
||||||
import { CollapsedPath } from './path';
|
|
||||||
import { SourceFilters } from './source_filters';
|
import { SourceFilters } from './source_filters';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -579,7 +578,6 @@ export interface OptimizerResult {
|
|||||||
liquidityDelivered: CollapsedFill[] | DexSample<MultiHopFillData>;
|
liquidityDelivered: CollapsedFill[] | DexSample<MultiHopFillData>;
|
||||||
marketSideLiquidity: MarketSideLiquidity;
|
marketSideLiquidity: MarketSideLiquidity;
|
||||||
adjustedRate: BigNumber;
|
adjustedRate: BigNumber;
|
||||||
unoptimizedPath?: CollapsedPath;
|
|
||||||
takerAmountPerEth: BigNumber;
|
takerAmountPerEth: BigNumber;
|
||||||
makerAmountPerEth: BigNumber;
|
makerAmountPerEth: BigNumber;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -952,9 +952,10 @@
|
|||||||
typedoc "~0.16.11"
|
typedoc "~0.16.11"
|
||||||
yargs "^10.0.3"
|
yargs "^10.0.3"
|
||||||
|
|
||||||
"@0x/neon-router@^0.3.3":
|
"@0x/neon-router@^0.3.5":
|
||||||
version "0.3.3"
|
version "0.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.3.3.tgz#dab540f4cd2aea6441ba29cbc35c28ca3f7a2b4f"
|
resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.3.5.tgz#895e7a2dc65d492a413daaea283cbc0ca6df83fa"
|
||||||
|
integrity sha512-8wizP3smc5o4jVg1smZzCCFo4ohOrgDhO4JFjF+/oNHbFImlGHOvmH9HQ2FJXAXiLEOTxrbp3T5XxP5GNATq3w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@mapbox/node-pre-gyp" "^1.0.5"
|
"@mapbox/node-pre-gyp" "^1.0.5"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user