@0x/asset-swapper
: Rebase and fix some minor bugs.
This commit is contained in:
parent
f901c401b7
commit
d0805d4bbb
@ -21,8 +21,9 @@ import {
|
|||||||
} from './types';
|
} from './types';
|
||||||
import { assert } from './utils/assert';
|
import { assert } from './utils/assert';
|
||||||
import { calculateLiquidity } from './utils/calculate_liquidity';
|
import { calculateLiquidity } from './utils/calculate_liquidity';
|
||||||
import { DexOrderSampler, MarketOperationUtils } from './utils/market_operation_utils';
|
import { MarketOperationUtils } from './utils/market_operation_utils';
|
||||||
import { createDummyOrderForSampler } from './utils/market_operation_utils/orders';
|
import { createDummyOrderForSampler } from './utils/market_operation_utils/orders';
|
||||||
|
import { DexOrderSampler } from './utils/market_operation_utils/sampler';
|
||||||
import { orderPrunerUtils } from './utils/order_prune_utils';
|
import { orderPrunerUtils } from './utils/order_prune_utils';
|
||||||
import { OrderStateUtils } from './utils/order_state_utils';
|
import { OrderStateUtils } from './utils/order_state_utils';
|
||||||
import { ProtocolFeeUtils } from './utils/protocol_fee_utils';
|
import { ProtocolFeeUtils } from './utils/protocol_fee_utils';
|
||||||
|
@ -1,234 +0,0 @@
|
|||||||
import { assert } from '@0x/assert';
|
|
||||||
import { ContractAddresses } from '@0x/contract-addresses';
|
|
||||||
import { assetDataUtils, generatePseudoRandomSalt } from '@0x/order-utils';
|
|
||||||
import { SignedOrder } from '@0x/types';
|
|
||||||
import { AbiEncoder, BigNumber } from '@0x/utils';
|
|
||||||
|
|
||||||
import { constants } from '../../constants';
|
|
||||||
|
|
||||||
import { constants as marketOperationUtilConstants } from './constants';
|
|
||||||
import {
|
|
||||||
AggregationError,
|
|
||||||
CollapsedFill,
|
|
||||||
ERC20BridgeSource,
|
|
||||||
NativeCollapsedFill,
|
|
||||||
OptimizedMarketOrder,
|
|
||||||
OrderDomain,
|
|
||||||
} from './types';
|
|
||||||
|
|
||||||
const { NULL_BYTES, NULL_ADDRESS, ZERO_AMOUNT } = constants;
|
|
||||||
const { INFINITE_TIMESTAMP_SEC, WALLET_SIGNATURE } = marketOperationUtilConstants;
|
|
||||||
|
|
||||||
export class CreateOrderUtils {
|
|
||||||
private readonly _contractAddress: ContractAddresses;
|
|
||||||
|
|
||||||
// utility function for asset-swapper to ignore market operation utils for specific asset types
|
|
||||||
public static convertNativeOrderToFullyFillableOptimizedOrders(order: SignedOrder): OptimizedMarketOrder {
|
|
||||||
return {
|
|
||||||
...order,
|
|
||||||
fillableMakerAssetAmount: order.makerAssetAmount,
|
|
||||||
fillableTakerAssetAmount: order.takerAssetAmount,
|
|
||||||
fillableTakerFeeAmount: order.takerFee,
|
|
||||||
fill: {
|
|
||||||
source: ERC20BridgeSource.Native,
|
|
||||||
totalMakerAssetAmount: order.makerAssetAmount,
|
|
||||||
totalTakerAssetAmount: order.takerAssetAmount,
|
|
||||||
subFills: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(contractAddress: ContractAddresses) {
|
|
||||||
this._contractAddress = contractAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert sell fills into orders.
|
|
||||||
public createSellOrdersFromPath(
|
|
||||||
orderDomain: OrderDomain,
|
|
||||||
inputToken: string,
|
|
||||||
outputToken: string,
|
|
||||||
path: CollapsedFill[],
|
|
||||||
bridgeSlippage: number,
|
|
||||||
liquidityProviderAddress?: string,
|
|
||||||
): OptimizedMarketOrder[] {
|
|
||||||
const orders: OptimizedMarketOrder[] = [];
|
|
||||||
for (const fill of path) {
|
|
||||||
if (fill.source === ERC20BridgeSource.Native) {
|
|
||||||
orders.push(createNativeOrder(fill));
|
|
||||||
} else {
|
|
||||||
orders.push(
|
|
||||||
createBridgeOrder(
|
|
||||||
orderDomain,
|
|
||||||
fill,
|
|
||||||
this._getBridgeAddressFromSource(fill.source, liquidityProviderAddress),
|
|
||||||
outputToken,
|
|
||||||
inputToken,
|
|
||||||
bridgeSlippage,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return orders;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert buy fills into orders.
|
|
||||||
public createBuyOrdersFromPath(
|
|
||||||
orderDomain: OrderDomain,
|
|
||||||
inputToken: string,
|
|
||||||
outputToken: string,
|
|
||||||
path: CollapsedFill[],
|
|
||||||
bridgeSlippage: number,
|
|
||||||
liquidityProviderAddress?: string,
|
|
||||||
): OptimizedMarketOrder[] {
|
|
||||||
const orders: OptimizedMarketOrder[] = [];
|
|
||||||
for (const fill of path) {
|
|
||||||
if (fill.source === ERC20BridgeSource.Native) {
|
|
||||||
orders.push(createNativeOrder(fill));
|
|
||||||
} else {
|
|
||||||
orders.push(
|
|
||||||
createBridgeOrder(
|
|
||||||
orderDomain,
|
|
||||||
fill,
|
|
||||||
this._getBridgeAddressFromSource(fill.source, liquidityProviderAddress),
|
|
||||||
inputToken,
|
|
||||||
outputToken,
|
|
||||||
bridgeSlippage,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return orders;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getBridgeAddressFromSource(source: ERC20BridgeSource, liquidityProviderAddress?: string): string {
|
|
||||||
switch (source) {
|
|
||||||
case ERC20BridgeSource.Eth2Dai:
|
|
||||||
return this._contractAddress.eth2DaiBridge;
|
|
||||||
case ERC20BridgeSource.Kyber:
|
|
||||||
return this._contractAddress.kyberBridge;
|
|
||||||
case ERC20BridgeSource.Uniswap:
|
|
||||||
return this._contractAddress.uniswapBridge;
|
|
||||||
case ERC20BridgeSource.CurveUsdcDai:
|
|
||||||
case ERC20BridgeSource.CurveUsdcDaiUsdt:
|
|
||||||
case ERC20BridgeSource.CurveUsdcDaiUsdtTusd:
|
|
||||||
case ERC20BridgeSource.CurveUsdcDaiUsdtBusd:
|
|
||||||
return this._contractAddress.curveBridge;
|
|
||||||
case ERC20BridgeSource.LiquidityProvider:
|
|
||||||
if (liquidityProviderAddress === undefined) {
|
|
||||||
throw new Error(
|
|
||||||
'Cannot create a LiquidityProvider order without a LiquidityProvider pool address.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
assert.isETHAddressHex('liquidityProviderAddress', liquidityProviderAddress);
|
|
||||||
return liquidityProviderAddress;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
throw new Error(AggregationError.NoBridgeForSource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createBridgeOrder(
|
|
||||||
orderDomain: OrderDomain,
|
|
||||||
fill: CollapsedFill,
|
|
||||||
bridgeAddress: string,
|
|
||||||
makerToken: string,
|
|
||||||
takerToken: string,
|
|
||||||
slippage: number,
|
|
||||||
isBuy: boolean = false,
|
|
||||||
): OptimizedMarketOrder {
|
|
||||||
let makerAssetData;
|
|
||||||
if (Object.keys(constants.DEFAULT_CURVE_OPTS).includes(fill.source)) {
|
|
||||||
const { curveAddress, tokens, version } = constants.DEFAULT_CURVE_OPTS[fill.source];
|
|
||||||
const fromTokenIdx = tokens.indexOf(takerToken);
|
|
||||||
const toTokenIdx = tokens.indexOf(makerToken);
|
|
||||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
|
||||||
makerToken,
|
|
||||||
bridgeAddress,
|
|
||||||
createCurveBridgeData(curveAddress, fromTokenIdx, toTokenIdx, version),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
|
||||||
makerToken,
|
|
||||||
bridgeAddress,
|
|
||||||
createBridgeData(takerToken),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
makerAddress: bridgeAddress,
|
|
||||||
makerAssetData,
|
|
||||||
takerAssetData: assetDataUtils.encodeERC20AssetData(takerToken),
|
|
||||||
...createCommonOrderFields(orderDomain, fill, slippage, isBuy),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function createBridgeData(tokenAddress: string): string {
|
|
||||||
const encoder = AbiEncoder.create([{ name: 'tokenAddress', type: 'address' }]);
|
|
||||||
return encoder.encode({ tokenAddress });
|
|
||||||
}
|
|
||||||
|
|
||||||
function createCurveBridgeData(
|
|
||||||
curveAddress: string,
|
|
||||||
fromTokenIdx: number,
|
|
||||||
toTokenIdx: number,
|
|
||||||
version: number,
|
|
||||||
): string {
|
|
||||||
const curveBridgeDataEncoder = AbiEncoder.create([
|
|
||||||
{ name: 'curveAddress', type: 'address' },
|
|
||||||
{ name: 'fromTokenIdx', type: 'int128' },
|
|
||||||
{ name: 'toTokenIdx', type: 'int128' },
|
|
||||||
{ name: 'version', type: 'int128' },
|
|
||||||
]);
|
|
||||||
return curveBridgeDataEncoder.encode([curveAddress, fromTokenIdx, toTokenIdx, version]);
|
|
||||||
}
|
|
||||||
|
|
||||||
type CommonOrderFields = Pick<
|
|
||||||
OptimizedMarketOrder,
|
|
||||||
Exclude<keyof OptimizedMarketOrder, 'makerAddress' | 'makerAssetData' | 'takerAssetData'>
|
|
||||||
>;
|
|
||||||
|
|
||||||
function createCommonOrderFields(
|
|
||||||
orderDomain: OrderDomain,
|
|
||||||
fill: CollapsedFill,
|
|
||||||
slippage: number,
|
|
||||||
isBuy: boolean = false,
|
|
||||||
): CommonOrderFields {
|
|
||||||
const makerAssetAmountAdjustedWithSlippage = isBuy
|
|
||||||
? fill.totalMakerAssetAmount
|
|
||||||
: fill.totalMakerAssetAmount.times(1 - slippage).integerValue(BigNumber.ROUND_DOWN);
|
|
||||||
const takerAssetAmountAdjustedWithSlippage = isBuy
|
|
||||||
? fill.totalTakerAssetAmount.times(slippage + 1).integerValue(BigNumber.ROUND_UP)
|
|
||||||
: fill.totalTakerAssetAmount;
|
|
||||||
return {
|
|
||||||
fill,
|
|
||||||
takerAddress: NULL_ADDRESS,
|
|
||||||
senderAddress: NULL_ADDRESS,
|
|
||||||
feeRecipientAddress: NULL_ADDRESS,
|
|
||||||
salt: generatePseudoRandomSalt(),
|
|
||||||
expirationTimeSeconds: INFINITE_TIMESTAMP_SEC,
|
|
||||||
makerFeeAssetData: NULL_BYTES,
|
|
||||||
takerFeeAssetData: NULL_BYTES,
|
|
||||||
makerFee: ZERO_AMOUNT,
|
|
||||||
takerFee: ZERO_AMOUNT,
|
|
||||||
makerAssetAmount: makerAssetAmountAdjustedWithSlippage,
|
|
||||||
fillableMakerAssetAmount: makerAssetAmountAdjustedWithSlippage,
|
|
||||||
takerAssetAmount: takerAssetAmountAdjustedWithSlippage,
|
|
||||||
fillableTakerAssetAmount: takerAssetAmountAdjustedWithSlippage,
|
|
||||||
fillableTakerFeeAmount: ZERO_AMOUNT,
|
|
||||||
signature: WALLET_SIGNATURE,
|
|
||||||
...orderDomain,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNativeOrder(fill: CollapsedFill): OptimizedMarketOrder {
|
|
||||||
return {
|
|
||||||
fill: {
|
|
||||||
source: fill.source,
|
|
||||||
totalMakerAssetAmount: fill.totalMakerAssetAmount,
|
|
||||||
totalTakerAssetAmount: fill.totalTakerAssetAmount,
|
|
||||||
subFills: fill.subFills,
|
|
||||||
},
|
|
||||||
...(fill as NativeCollapsedFill).nativeOrder,
|
|
||||||
};
|
|
||||||
}
|
|
@ -20,8 +20,6 @@ import {
|
|||||||
OrderDomain,
|
OrderDomain,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
export { DexOrderSampler } from './sampler';
|
|
||||||
|
|
||||||
export class MarketOperationUtils {
|
export class MarketOperationUtils {
|
||||||
private readonly _wethAddress: string;
|
private readonly _wethAddress: string;
|
||||||
|
|
||||||
@ -298,6 +296,7 @@ export class MarketOperationUtils {
|
|||||||
orderDomain: this._orderDomain,
|
orderDomain: this._orderDomain,
|
||||||
contractAddresses: this.contractAddresses,
|
contractAddresses: this.contractAddresses,
|
||||||
bridgeSlippage: opts.bridgeSlippage || 0,
|
bridgeSlippage: opts.bridgeSlippage || 0,
|
||||||
|
liquidityProviderAddress: opts.liquidityProviderAddress,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ export interface CreateOrderFromPathOpts {
|
|||||||
orderDomain: OrderDomain;
|
orderDomain: OrderDomain;
|
||||||
contractAddresses: ContractAddresses;
|
contractAddresses: ContractAddresses;
|
||||||
bridgeSlippage: number;
|
bridgeSlippage: number;
|
||||||
|
liquidityProviderAddress?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert sell fills into orders.
|
// Convert sell fills into orders.
|
||||||
@ -135,19 +136,24 @@ export function createOrdersFromPath(path: Fill[], opts: CreateOrderFromPathOpts
|
|||||||
return orders;
|
return orders;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBridgeAddressFromSource(source: ERC20BridgeSource, contractAddresses: ContractAddresses): string {
|
function getBridgeAddressFromSource(source: ERC20BridgeSource, opts: CreateOrderFromPathOpts): string {
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case ERC20BridgeSource.Eth2Dai:
|
case ERC20BridgeSource.Eth2Dai:
|
||||||
return contractAddresses.eth2DaiBridge;
|
return opts.contractAddresses.eth2DaiBridge;
|
||||||
case ERC20BridgeSource.Kyber:
|
case ERC20BridgeSource.Kyber:
|
||||||
return contractAddresses.kyberBridge;
|
return opts.contractAddresses.kyberBridge;
|
||||||
case ERC20BridgeSource.Uniswap:
|
case ERC20BridgeSource.Uniswap:
|
||||||
return contractAddresses.uniswapBridge;
|
return opts.contractAddresses.uniswapBridge;
|
||||||
case ERC20BridgeSource.CurveUsdcDai:
|
case ERC20BridgeSource.CurveUsdcDai:
|
||||||
case ERC20BridgeSource.CurveUsdcDaiUsdt:
|
case ERC20BridgeSource.CurveUsdcDaiUsdt:
|
||||||
case ERC20BridgeSource.CurveUsdcDaiUsdtTusd:
|
case ERC20BridgeSource.CurveUsdcDaiUsdtTusd:
|
||||||
case ERC20BridgeSource.CurveUsdcDaiUsdtBusd:
|
case ERC20BridgeSource.CurveUsdcDaiUsdtBusd:
|
||||||
return contractAddresses.curveBridge;
|
return opts.contractAddresses.curveBridge;
|
||||||
|
case ERC20BridgeSource.LiquidityProvider:
|
||||||
|
if (opts.liquidityProviderAddress === undefined) {
|
||||||
|
throw new Error('Cannot create a LiquidityProvider order without a LiquidityProvider pool address.');
|
||||||
|
}
|
||||||
|
return opts.liquidityProviderAddress;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -157,7 +163,7 @@ function getBridgeAddressFromSource(source: ERC20BridgeSource, contractAddresses
|
|||||||
function createBridgeOrder(fill: CollapsedFill, opts: CreateOrderFromPathOpts): OptimizedMarketOrder {
|
function createBridgeOrder(fill: CollapsedFill, opts: CreateOrderFromPathOpts): OptimizedMarketOrder {
|
||||||
const takerToken = opts.side === MarketOperation.Sell ? opts.inputToken : opts.outputToken;
|
const takerToken = opts.side === MarketOperation.Sell ? opts.inputToken : opts.outputToken;
|
||||||
const makerToken = opts.side === MarketOperation.Sell ? opts.outputToken : opts.inputToken;
|
const makerToken = opts.side === MarketOperation.Sell ? opts.outputToken : opts.inputToken;
|
||||||
const bridgeAddress = getBridgeAddressFromSource(fill.source, opts.contractAddresses);
|
const bridgeAddress = getBridgeAddressFromSource(fill.source, opts);
|
||||||
|
|
||||||
let makerAssetData;
|
let makerAssetData;
|
||||||
if (Object.keys(DEFAULT_CURVE_OPTS).includes(fill.source)) {
|
if (Object.keys(DEFAULT_CURVE_OPTS).includes(fill.source)) {
|
||||||
|
@ -30,7 +30,7 @@ const RATE_DECIMALS = 8;
|
|||||||
function hillClimbToOptimalPath(paths: Fill[][], targetInput: BigNumber): Fill[] {
|
function hillClimbToOptimalPath(paths: Fill[][], targetInput: BigNumber): Fill[] {
|
||||||
// Flatten and sort path fills by descending ADJUSTED rate.
|
// Flatten and sort path fills by descending ADJUSTED rate.
|
||||||
const fills = paths
|
const fills = paths
|
||||||
.reduce((acc, p) => acc.concat(p))
|
.reduce((acc, p) => acc.concat(p), [])
|
||||||
.sort((a, b) => b.adjustedRate.dp(RATE_DECIMALS).comparedTo(a.adjustedRate.dp(RATE_DECIMALS)));
|
.sort((a, b) => b.adjustedRate.dp(RATE_DECIMALS).comparedTo(a.adjustedRate.dp(RATE_DECIMALS)));
|
||||||
// Build up a path by picking the next best, valid fill until we meet our input target.
|
// Build up a path by picking the next best, valid fill until we meet our input target.
|
||||||
const path: Fill[] = [];
|
const path: Fill[] = [];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { BigNumber, ERC20BridgeSource, SignedOrder } from '../..';
|
import { BigNumber, ERC20BridgeSource, SignedOrder } from '../..';
|
||||||
import { constants } from '../../constants';
|
|
||||||
|
|
||||||
|
import { DEFAULT_CURVE_OPTS } from './constants';
|
||||||
import { BatchedOperation, DexSample } from './types';
|
import { BatchedOperation, DexSample } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -233,8 +233,8 @@ export const samplerOperations = {
|
|||||||
},
|
},
|
||||||
getLiquidityProviderFromRegistry(
|
getLiquidityProviderFromRegistry(
|
||||||
registryAddress: string,
|
registryAddress: string,
|
||||||
takerToken: string,
|
|
||||||
makerToken: string,
|
makerToken: string,
|
||||||
|
takerToken: string,
|
||||||
): BatchedOperation<string> {
|
): BatchedOperation<string> {
|
||||||
return {
|
return {
|
||||||
encodeCall: contract => {
|
encodeCall: contract => {
|
||||||
@ -263,8 +263,8 @@ export const samplerOperations = {
|
|||||||
batchedOperation = samplerOperations.getUniswapSellQuotes(makerToken, takerToken, takerFillAmounts);
|
batchedOperation = samplerOperations.getUniswapSellQuotes(makerToken, takerToken, takerFillAmounts);
|
||||||
} else if (source === ERC20BridgeSource.Kyber) {
|
} else if (source === ERC20BridgeSource.Kyber) {
|
||||||
batchedOperation = samplerOperations.getKyberSellQuotes(makerToken, takerToken, takerFillAmounts);
|
batchedOperation = samplerOperations.getKyberSellQuotes(makerToken, takerToken, takerFillAmounts);
|
||||||
} else if (Object.keys(constants.DEFAULT_CURVE_OPTS).includes(source)) {
|
} else if (Object.keys(DEFAULT_CURVE_OPTS).includes(source)) {
|
||||||
const { curveAddress, tokens } = constants.DEFAULT_CURVE_OPTS[source];
|
const { curveAddress, tokens } = DEFAULT_CURVE_OPTS[source];
|
||||||
const fromTokenIdx = tokens.indexOf(takerToken);
|
const fromTokenIdx = tokens.indexOf(takerToken);
|
||||||
const toTokenIdx = tokens.indexOf(makerToken);
|
const toTokenIdx = tokens.indexOf(makerToken);
|
||||||
if (fromTokenIdx !== -1 && toTokenIdx !== -1) {
|
if (fromTokenIdx !== -1 && toTokenIdx !== -1) {
|
||||||
|
@ -652,7 +652,7 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
Web3Wrapper.toBaseUnitAmount(10, 18),
|
Web3Wrapper.toBaseUnitAmount(10, 18),
|
||||||
{ excludedSources: SELL_SOURCES, numSamples: 4 },
|
{ excludedSources: SELL_SOURCES, numSamples: 4, bridgeSlippage: 0 },
|
||||||
);
|
);
|
||||||
expect(result.length).to.eql(1);
|
expect(result.length).to.eql(1);
|
||||||
expect(result[0].makerAddress).to.eql(liquidityProviderAddress);
|
expect(result[0].makerAddress).to.eql(liquidityProviderAddress);
|
||||||
@ -667,8 +667,8 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
expect(getSellQuotesParams.sources).contains(ERC20BridgeSource.LiquidityProvider);
|
expect(getSellQuotesParams.sources).contains(ERC20BridgeSource.LiquidityProvider);
|
||||||
expect(getSellQuotesParams.liquidityProviderAddress).is.eql(registryAddress);
|
expect(getSellQuotesParams.liquidityProviderAddress).is.eql(registryAddress);
|
||||||
expect(getLiquidityProviderParams.registryAddress).is.eql(registryAddress);
|
expect(getLiquidityProviderParams.registryAddress).is.eql(registryAddress);
|
||||||
expect(getLiquidityProviderParams.makerToken).is.eql(xAsset);
|
expect(getLiquidityProviderParams.makerToken).is.eql(yAsset);
|
||||||
expect(getLiquidityProviderParams.takerToken).is.eql(yAsset);
|
expect(getLiquidityProviderParams.takerToken).is.eql(xAsset);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -8,8 +8,9 @@ import 'mocha';
|
|||||||
|
|
||||||
import { constants } from '../src/constants';
|
import { constants } from '../src/constants';
|
||||||
import { CalculateSwapQuoteOpts, SignedOrderWithFillableAmounts } from '../src/types';
|
import { CalculateSwapQuoteOpts, SignedOrderWithFillableAmounts } from '../src/types';
|
||||||
import { DexOrderSampler, MarketOperationUtils } from '../src/utils/market_operation_utils/';
|
import { MarketOperationUtils } from '../src/utils/market_operation_utils/';
|
||||||
import { DEFAULT_GET_MARKET_ORDERS_OPTS, SELL_SOURCES } from '../src/utils/market_operation_utils/constants';
|
import { DEFAULT_GET_MARKET_ORDERS_OPTS, SELL_SOURCES } from '../src/utils/market_operation_utils/constants';
|
||||||
|
import { DexOrderSampler } from '../src/utils/market_operation_utils/sampler';
|
||||||
import { ProtocolFeeUtils } from '../src/utils/protocol_fee_utils';
|
import { ProtocolFeeUtils } from '../src/utils/protocol_fee_utils';
|
||||||
import { SwapQuoteCalculator } from '../src/utils/swap_quote_calculator';
|
import { SwapQuoteCalculator } from '../src/utils/swap_quote_calculator';
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user