Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
@0x/asset-swapper: Reeeeeefactor + fallback orders.
Browse files Browse the repository at this point in the history
  • Loading branch information
merklejerk committed Mar 6, 2020
1 parent b4d7f95 commit 4b54365
Show file tree
Hide file tree
Showing 24 changed files with 949 additions and 1,300 deletions.
17 changes: 17 additions & 0 deletions packages/asset-swapper/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
[
{
"version": "4.5.0",
"changes": [
{
"note": "Big refactor of market operation utils",
"pr": 2513
},
{
"note": "Revamp fill optimization algorithm",
"pr": 2513
},
{
"note": "Add fallback orders to quotes",
"pr": 2513
}
]
},
{
"version": "4.4.0",
"changes": [
Expand Down
46 changes: 3 additions & 43 deletions packages/asset-swapper/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import {
SwapQuoterOpts,
} from './types';

import { constants as marketOperationUtilConstants } from './utils/market_operation_utils/constants';
import { ERC20BridgeSource } from './utils/market_operation_utils/types';
import { DEFAULT_GET_MARKET_ORDERS_OPTS } from './utils/market_operation_utils/constants';

const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info';
const NULL_BYTES = '0x';
Expand Down Expand Up @@ -60,47 +59,9 @@ const DEFAULT_FORWARDER_SWAP_QUOTE_EXECUTE_OPTS: SwapQuoteExecutionOpts = DEFAUL

const DEFAULT_SWAP_QUOTE_REQUEST_OPTS: SwapQuoteRequestOpts = {
...{
slippagePercentage: 0.2, // 20% slippage protection,
},
...marketOperationUtilConstants.DEFAULT_GET_MARKET_ORDERS_OPTS,
};

// Mainnet Curve configuration
const DEFAULT_CURVE_OPTS: { [source: string]: { version: number; curveAddress: string; tokens: string[] } } = {
[ERC20BridgeSource.CurveUsdcDai]: {
version: 1,
curveAddress: '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56',
tokens: ['0x6b175474e89094c44da98b954eedeac495271d0f', '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'],
},
[ERC20BridgeSource.CurveUsdcDaiUsdt]: {
version: 1,
curveAddress: '0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c',
tokens: [
'0x6b175474e89094c44da98b954eedeac495271d0f',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0xdac17f958d2ee523a2206206994597c13d831ec7',
],
},
[ERC20BridgeSource.CurveUsdcDaiUsdtTusd]: {
version: 1,
curveAddress: '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51',
tokens: [
'0x6b175474e89094c44da98b954eedeac495271d0f',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0xdac17f958d2ee523a2206206994597c13d831ec7',
'0x0000000000085d4780b73119b644ae5ecd22b376',
],
},
[ERC20BridgeSource.CurveUsdcDaiUsdtBusd]: {
version: 1,
curveAddress: '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27',
tokens: [
'0x6b175474e89094c44da98b954eedeac495271d0f',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0xdac17f958d2ee523a2206206994597c13d831ec7',
'0x4fabb145d64652a948d72533023f6e7a623c7c53',
],
slippagePercentage: 0.05, // 5% slippage protection,
},
...DEFAULT_GET_MARKET_ORDERS_OPTS,
};

export const constants = {
Expand All @@ -123,5 +84,4 @@ export const constants = {
PROTOCOL_FEE_UTILS_POLLING_INTERVAL_IN_MS,
MARKET_UTILS_AMOUNT_BUFFER_PERCENTAGE,
BRIDGE_ASSET_DATA_PREFIX: '0xdc1600f3',
DEFAULT_CURVE_OPTS,
};
6 changes: 3 additions & 3 deletions packages/asset-swapper/src/swap_quoter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
import { assert } from './utils/assert';
import { calculateLiquidity } from './utils/calculate_liquidity';
import { DexOrderSampler, MarketOperationUtils } from './utils/market_operation_utils';
import { dummyOrderUtils } from './utils/market_operation_utils/dummy_order_utils';
import { createDummyOrderForSampler } from './utils/market_operation_utils/orders';
import { orderPrunerUtils } from './utils/order_prune_utils';
import { OrderStateUtils } from './utils/order_state_utils';
import { ProtocolFeeUtils } from './utils/protocol_fee_utils';
Expand Down Expand Up @@ -256,7 +256,7 @@ export class SwapQuoter {
);
if (prunedOrders.length === 0) {
return [
dummyOrderUtils.createDummyOrderForSampler(
createDummyOrderForSampler(
makerAssetDatas[i],
takerAssetData,
this._contractAddresses.uniswapBridge,
Expand Down Expand Up @@ -529,7 +529,7 @@ export class SwapQuoter {
// if no native orders, pass in a dummy order for the sampler to have required metadata for sampling
if (prunedOrders.length === 0) {
prunedOrders = [
dummyOrderUtils.createDummyOrderForSampler(
createDummyOrderForSampler(
makerAssetData,
takerAssetData,
this._contractAddresses.uniswapBridge,
Expand Down
17 changes: 11 additions & 6 deletions packages/asset-swapper/src/utils/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import * as _ from 'lodash';

import { MarketOperation, OrderProviderRequest, SwapQuote, SwapQuoteInfo } from '../types';

import { utils } from './utils';
import {
isAssetDataEquivalent,
isExactAssetData,
isOrderTakerFeePayableWithMakerAsset,
isOrderTakerFeePayableWithTakerAsset,
} from './utils';

export const assert = {
...sharedAssert,
Expand Down Expand Up @@ -36,13 +41,13 @@ export const assert = {
): void {
_.every(orders, (order: SignedOrder, index: number) => {
assert.assert(
utils.isAssetDataEquivalent(takerAssetData, order.takerAssetData),
isAssetDataEquivalent(takerAssetData, order.takerAssetData),
`Expected ${variableName}[${index}].takerAssetData to be ${takerAssetData} but found ${
order.takerAssetData
}`,
);
assert.assert(
utils.isAssetDataEquivalent(makerAssetData, order.makerAssetData),
isAssetDataEquivalent(makerAssetData, order.makerAssetData),
`Expected ${variableName}[${index}].makerAssetData to be ${makerAssetData} but found ${
order.makerAssetData
}`,
Expand All @@ -53,8 +58,8 @@ export const assert = {
_.every(orders, (order: T, index: number) => {
assert.assert(
order.takerFee.isZero() ||
utils.isOrderTakerFeePayableWithTakerAsset(order) ||
utils.isOrderTakerFeePayableWithMakerAsset(order),
isOrderTakerFeePayableWithTakerAsset(order) ||
isOrderTakerFeePayableWithMakerAsset(order),
`Expected ${variableName}[${index}].takerFeeAssetData to be ${order.makerAssetData} or ${
order.takerAssetData
} but found ${order.takerFeeAssetData}`,
Expand All @@ -72,7 +77,7 @@ export const assert = {
},
isValidForwarderSignedOrder(variableName: string, order: SignedOrder, wethAssetData: string): void {
assert.assert(
utils.isExactAssetData(order.takerAssetData, wethAssetData),
isExactAssetData(order.takerAssetData, wethAssetData),
`Expected ${variableName} to have takerAssetData set as ${wethAssetData}, but is ${order.takerAssetData}`,
);
},
Expand Down
6 changes: 3 additions & 3 deletions packages/asset-swapper/src/utils/calculate_liquidity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import { BigNumber } from '@0x/utils';

import { LiquidityForTakerMakerAssetDataPair, SignedOrderWithFillableAmounts } from '../types';

import { utils } from './utils';
import { isOrderTakerFeePayableWithMakerAsset, isOrderTakerFeePayableWithTakerAsset } from './utils';

export const calculateLiquidity = (
prunedOrders: SignedOrderWithFillableAmounts[],
): LiquidityForTakerMakerAssetDataPair => {
const liquidityInBigNumbers = prunedOrders.reduce(
(acc, order) => {
const fillableMakerAssetAmount = utils.isOrderTakerFeePayableWithMakerAsset(order)
const fillableMakerAssetAmount = isOrderTakerFeePayableWithMakerAsset(order)
? order.fillableMakerAssetAmount.minus(order.fillableTakerFeeAmount)
: order.fillableMakerAssetAmount;
const fillableTakerAssetAmount = utils.isOrderTakerFeePayableWithTakerAsset(order)
const fillableTakerAssetAmount = isOrderTakerFeePayableWithTakerAsset(order)
? order.fillableTakerAssetAmount.plus(order.fillableTakerFeeAmount)
: order.fillableTakerAssetAmount;
return {
Expand Down
6 changes: 3 additions & 3 deletions packages/asset-swapper/src/utils/fillable_amounts_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ import * as _ from 'lodash';

import { SignedOrderWithFillableAmounts } from '../types';

import { utils } from './utils';
import { isOrderTakerFeePayableWithMakerAsset, isOrderTakerFeePayableWithTakerAsset } from './utils';

export const fillableAmountsUtils = {
getTakerAssetAmountSwappedAfterOrderFees(order: SignedOrderWithFillableAmounts): BigNumber {
if (utils.isOrderTakerFeePayableWithTakerAsset(order)) {
if (isOrderTakerFeePayableWithTakerAsset(order)) {
return order.fillableTakerAssetAmount.plus(order.fillableTakerFeeAmount);
} else {
return order.fillableTakerAssetAmount;
}
},
getMakerAssetAmountSwappedAfterOrderFees(order: SignedOrderWithFillableAmounts): BigNumber {
if (utils.isOrderTakerFeePayableWithMakerAsset(order)) {
if (isOrderTakerFeePayableWithMakerAsset(order)) {
return order.fillableMakerAssetAmount.minus(order.fillableTakerFeeAmount);
} else {
return order.fillableMakerAssetAmount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BigNumber } from '@0x/utils';

import { ERC20BridgeSource, GetMarketOrdersOpts } from './types';

const INFINITE_TIMESTAMP_SEC = new BigNumber(2524604400);
// tslint:disable: custom-no-magic-numbers

/**
* Valid sources for market sell.
Expand All @@ -25,28 +25,66 @@ export const BUY_SOURCES = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.Eth2Dai

export const DEFAULT_GET_MARKET_ORDERS_OPTS: GetMarketOrdersOpts = {
// tslint:disable-next-line: custom-no-magic-numbers
runLimit: 2 ** 15,
excludedSources: [],
bridgeSlippage: 0.0005,
dustFractionThreshold: 0.0025,
numSamples: 13,
noConflicts: true,
numSamples: 20,
sampleDistributionBase: 1.05,
fees: {},
allowFallback: true,
};

/**
* Sources to poll for ETH fee price estimates.
*/
export const FEE_QUOTE_SOURCES = SELL_SOURCES;

export const constants = {
INFINITE_TIMESTAMP_SEC,
SELL_SOURCES,
BUY_SOURCES,
DEFAULT_GET_MARKET_ORDERS_OPTS,
ERC20_PROXY_ID: '0xf47261b0',
FEE_QUOTE_SOURCES,
WALLET_SIGNATURE: '0x04',
ONE_ETHER: new BigNumber(1e18),
/**
* Mainnet Curve configuration
*/
export const DEFAULT_CURVE_OPTS: { [source: string]: { version: number; curveAddress: string; tokens: string[] } } = {
[ERC20BridgeSource.CurveUsdcDai]: {
version: 1,
curveAddress: '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56',
tokens: ['0x6b175474e89094c44da98b954eedeac495271d0f', '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'],
},
[ERC20BridgeSource.CurveUsdcDaiUsdt]: {
version: 1,
curveAddress: '0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c',
tokens: [
'0x6b175474e89094c44da98b954eedeac495271d0f',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0xdac17f958d2ee523a2206206994597c13d831ec7',
],
},
[ERC20BridgeSource.CurveUsdcDaiUsdtTusd]: {
version: 1,
curveAddress: '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51',
tokens: [
'0x6b175474e89094c44da98b954eedeac495271d0f',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0xdac17f958d2ee523a2206206994597c13d831ec7',
'0x0000000000085d4780b73119b644ae5ecd22b376',
],
},
[ERC20BridgeSource.CurveUsdcDaiUsdtBusd]: {
version: 1,
curveAddress: '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27',
tokens: [
'0x6b175474e89094c44da98b954eedeac495271d0f',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0xdac17f958d2ee523a2206206994597c13d831ec7',
'0x4fabb145d64652a948d72533023f6e7a623c7c53',
],
},
};

export const ERC20_PROXY_ID = '0xf47261b0';
export const WALLET_SIGNATURE = '0x04';
export const ONE_ETHER = new BigNumber(1e18);
export const NEGATIVE_INF = new BigNumber('-Infinity');
export const POSITIVE_INF = new BigNumber('Infinity');
export const ZERO_AMOUNT = new BigNumber(0);
export const ONE_HOUR_IN_SECONDS = 60 * 60;
export const ONE_SECOND_MS = 1000;
export const NULL_BYTES = '0x';
export const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
Loading

0 comments on commit 4b54365

Please sign in to comment.