diff --git a/src/asset-swapper/quote_consumers/exchange_proxy_swap_quote_consumer.ts b/src/asset-swapper/quote_consumers/exchange_proxy_swap_quote_consumer.ts index 98cee18b3..d8a4dbf3f 100644 --- a/src/asset-swapper/quote_consumers/exchange_proxy_swap_quote_consumer.ts +++ b/src/asset-swapper/quote_consumers/exchange_proxy_swap_quote_consumer.ts @@ -41,7 +41,7 @@ import { NativeOtcOrderFillData, NativeRfqOrderFillData, OptimizedMarketBridgeOrder, - OptimizedMarketOrder, + OptimizedOrder, } from '../types'; import { @@ -727,7 +727,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { } } -function slipNonNativeOrders(quote: MarketSellSwapQuote | MarketBuySwapQuote): OptimizedMarketOrder[] { +function slipNonNativeOrders(quote: MarketSellSwapQuote | MarketBuySwapQuote): OptimizedOrder[] { const slippage = getMaxQuoteSlippageRate(quote); if (slippage === 0) { return quote.orders; diff --git a/src/asset-swapper/quote_consumers/quote_consumer_utils.ts b/src/asset-swapper/quote_consumers/quote_consumer_utils.ts index a1ca39e50..e029d47bf 100644 --- a/src/asset-swapper/quote_consumers/quote_consumer_utils.ts +++ b/src/asset-swapper/quote_consumers/quote_consumer_utils.ts @@ -7,7 +7,7 @@ import { SwapQuote, ERC20BridgeSource, OptimizedMarketBridgeOrder, - OptimizedMarketOrder, + OptimizedOrder, OptimizedOtcOrder, OptimizedRfqOrder, OptimizedLimitOrder, @@ -96,19 +96,19 @@ export function isBuyQuote(quote: SwapQuote): quote is MarketBuySwapQuote { return quote.type === MarketOperation.Buy; } -function isOptimizedBridgeOrder(x: OptimizedMarketOrder): x is OptimizedMarketBridgeOrder { +function isOptimizedBridgeOrder(x: OptimizedOrder): x is OptimizedMarketBridgeOrder { return x.type === FillQuoteTransformerOrderType.Bridge; } -function isOptimizedLimitOrder(x: OptimizedMarketOrder): x is OptimizedLimitOrder { +function isOptimizedLimitOrder(x: OptimizedOrder): x is OptimizedLimitOrder { return x.type === FillQuoteTransformerOrderType.Limit; } -function isOptimizedRfqOrder(x: OptimizedMarketOrder): x is OptimizedRfqOrder { +function isOptimizedRfqOrder(x: OptimizedOrder): x is OptimizedRfqOrder { return x.type === FillQuoteTransformerOrderType.Rfq; } -function isOptimizedOtcOrder(x: OptimizedMarketOrder): x is OptimizedOtcOrder { +function isOptimizedOtcOrder(x: OptimizedOrder): x is OptimizedOtcOrder { return x.type === FillQuoteTransformerOrderType.Otc; } @@ -117,7 +117,7 @@ function isOptimizedOtcOrder(x: OptimizedMarketOrder): x is OptimizedOtcOrder { * FillQuoteTransformer. */ export function getFQTTransformerDataFromOptimizedOrders( - orders: OptimizedMarketOrder[], + orders: OptimizedOrder[], ): Pick { const fqtData: Pick< FillQuoteTransformerData, diff --git a/src/asset-swapper/swap_quoter.ts b/src/asset-swapper/swap_quoter.ts index e189901d0..7df2f9c33 100644 --- a/src/asset-swapper/swap_quoter.ts +++ b/src/asset-swapper/swap_quoter.ts @@ -34,14 +34,7 @@ import { import { DexOrderSampler } from './utils/market_operation_utils/sampler'; import { SourceFilters } from './utils/market_operation_utils/source_filters'; import { OptimizerResultWithReport } from './utils/market_operation_utils/types'; -import { - ERC20BridgeSource, - FillData, - GasSchedule, - GetMarketOrdersOpts, - OptimizedMarketOrder, - Orderbook, -} from './types'; +import { ERC20BridgeSource, FillData, GasSchedule, GetMarketOrdersOpts, OptimizedOrder, Orderbook } from './types'; import { GasPriceUtils } from './utils/gas_price_utils'; import { QuoteRequestor } from './utils/quote_requestor'; import { QuoteFillResult, simulateBestCaseFill, simulateWorstCaseFill } from './utils/quote_simulation'; @@ -399,7 +392,7 @@ function createSwapQuote( } function calculateQuoteInfo( - optimizedOrders: OptimizedMarketOrder[], + optimizedOrders: OptimizedOrder[], operation: MarketOperation, assetFillAmount: BigNumber, gasPrice: BigNumber, @@ -430,7 +423,7 @@ function calculateQuoteInfo( } function calculateTwoHopQuoteInfo( - optimizedOrders: OptimizedMarketOrder[], + optimizedOrders: OptimizedOrder[], operation: MarketOperation, gasSchedule: GasSchedule, slippage: number, diff --git a/src/asset-swapper/types.ts b/src/asset-swapper/types.ts index 5f6dd139a..88ec45c26 100644 --- a/src/asset-swapper/types.ts +++ b/src/asset-swapper/types.ts @@ -248,7 +248,7 @@ interface SwapQuoteBase { takerToken: string; makerToken: string; gasPrice: BigNumber; - orders: OptimizedMarketOrder[]; + orders: OptimizedOrder[]; bestCaseQuoteInfo: SwapQuoteInfo; worstCaseQuoteInfo: SwapQuoteInfo; sourceBreakdown: SwapQuoteOrdersBreakdown; @@ -712,7 +712,7 @@ export interface GetMarketOrdersOpts { fillAdjustor: FillAdjustor; } -export interface OptimizedMarketOrderBase { +interface OptimizedMarketOrderBase { source: ERC20BridgeSource; fillData: TFillData; type: FillQuoteTransformerOrderType; // should correspond with TFillData @@ -741,14 +741,9 @@ export interface OptimizedOtcOrder extends OptimizedMarketOrderBase - | OptimizedMarketOrderBase - | OptimizedMarketOrderBase - | OptimizedMarketOrderBase; +export type OptimizedNativeOrder = OptimizedLimitOrder | OptimizedRfqOrder | OptimizedOtcOrder; + +export type OptimizedOrder = OptimizedMarketBridgeOrder | OptimizedNativeOrder; export abstract class Orderbook { public abstract getOrdersAsync( diff --git a/src/asset-swapper/utils/market_operation_utils/orders.ts b/src/asset-swapper/utils/market_operation_utils/orders.ts index d62ad23d9..5d4c2113b 100644 --- a/src/asset-swapper/utils/market_operation_utils/orders.ts +++ b/src/asset-swapper/utils/market_operation_utils/orders.ts @@ -13,8 +13,8 @@ import { NativeOtcOrderFillData, NativeRfqOrderFillData, OptimizedMarketBridgeOrder, - OptimizedMarketOrder, - OptimizedMarketOrderBase, + OptimizedOrder, + OptimizedNativeOrder, } from '../../types'; import { MAX_UINT256, ZERO_AMOUNT } from './constants'; @@ -58,7 +58,7 @@ export interface CreateOrderFromPathOpts { export function createOrdersFromTwoHopSample( sample: DexSample, opts: CreateOrderFromPathOpts, -): [OptimizedMarketOrder, OptimizedMarketOrder] { +): [OptimizedOrder, OptimizedOrder] { const [makerToken, takerToken] = getMakerTakerTokens(opts); const { firstHopSource, secondHopSource, intermediateToken } = sample.fillData; const firstHopFill: Fill = { @@ -548,13 +548,7 @@ function getFillTokenAmounts(fill: Fill, side: MarketOperation): [BigNumber, Big ]; } -export function createNativeOptimizedOrder( - fill: Fill, - side: MarketOperation, -): - | OptimizedMarketOrderBase - | OptimizedMarketOrderBase - | OptimizedMarketOrderBase { +export function createNativeOptimizedOrder(fill: Fill, side: MarketOperation): OptimizedNativeOrder { const fillData = fill.fillData; const [makerAmount, takerAmount] = getFillTokenAmounts(fill, side); const base = { diff --git a/src/asset-swapper/utils/market_operation_utils/path.ts b/src/asset-swapper/utils/market_operation_utils/path.ts index d9106bdb2..f4bdef765 100644 --- a/src/asset-swapper/utils/market_operation_utils/path.ts +++ b/src/asset-swapper/utils/market_operation_utils/path.ts @@ -4,7 +4,7 @@ import _ = require('lodash'); import { MarketOperation, NativeFillData, - OptimizedMarketOrder, + OptimizedOrder, ERC20BridgeSource, ExchangeProxyOverhead, Fill, @@ -42,7 +42,7 @@ const DEFAULT_PATH_PENALTY_OPTS: PathPenaltyOpts = { }; export class Path { - public orders?: OptimizedMarketOrder[]; + public orders?: OptimizedOrder[]; public sourceFlags = BigInt(0); protected _size: PathSize = { input: ZERO_AMOUNT, output: ZERO_AMOUNT }; protected _adjustedSize: PathSize = { input: ZERO_AMOUNT, output: ZERO_AMOUNT }; @@ -179,5 +179,5 @@ export class Path { } interface FinalizedPath extends Path { - readonly orders: OptimizedMarketOrder[]; + readonly orders: OptimizedOrder[]; } diff --git a/src/asset-swapper/utils/market_operation_utils/types.ts b/src/asset-swapper/utils/market_operation_utils/types.ts index db42d901f..cca904002 100644 --- a/src/asset-swapper/utils/market_operation_utils/types.ts +++ b/src/asset-swapper/utils/market_operation_utils/types.ts @@ -5,7 +5,7 @@ import { BigNumber } from '@0x/utils'; import { NativeOrderWithFillableAmounts, ERC20BridgeSource, - OptimizedMarketOrder, + OptimizedOrder, FillData, FeeSchedule, Fill, @@ -307,7 +307,7 @@ export interface SourceQuoteOperation ext } export interface OptimizerResult { - optimizedOrders: OptimizedMarketOrder[]; + optimizedOrders: OptimizedOrder[]; sourceFlags: bigint; liquidityDelivered: Readonly>; marketSideLiquidity: MarketSideLiquidity; diff --git a/src/asset-swapper/utils/quote_simulation.ts b/src/asset-swapper/utils/quote_simulation.ts index 4ec2432dc..0a4bdcd23 100644 --- a/src/asset-swapper/utils/quote_simulation.ts +++ b/src/asset-swapper/utils/quote_simulation.ts @@ -2,7 +2,7 @@ import { FillQuoteTransformerOrderType } from '@0x/protocol-utils'; import { BigNumber } from '@0x/utils'; import { constants } from '../constants'; -import { MarketOperation, GasSchedule, NativeLimitOrderFillData, OptimizedMarketOrder } from '../types'; +import { MarketOperation, GasSchedule, NativeLimitOrderFillData, OptimizedOrder } from '../types'; import { getNativeAdjustedTakerFeeAmount } from './utils'; @@ -61,7 +61,7 @@ const EMPTY_QUOTE_INTERMEDIATE_FILL_RESULT = { }; interface QuoteFillInfo { - orders: OptimizedMarketOrder[]; + orders: OptimizedOrder[]; fillAmount: BigNumber; gasPrice: BigNumber; side: MarketOperation; @@ -80,7 +80,7 @@ const DEFAULT_SIMULATED_FILL_QUOTE_INFO_OPTS = { }; export interface QuoteFillOrderCall { - order: OptimizedMarketOrder; + order: OptimizedOrder; // Total input amount defined in the order. totalOrderInput: BigNumber; // Total output amount defined in the order. @@ -176,7 +176,7 @@ export function fillQuoteOrders( return result; } -function hasProtocolFee(o: OptimizedMarketOrder): boolean { +function hasProtocolFee(o: OptimizedOrder): boolean { return o.type === FillQuoteTransformerOrderType.Limit; } @@ -299,7 +299,7 @@ function fromIntermediateQuoteFillResult(ir: IntermediateQuoteFillResult, quoteI }; } -function getTotalGasUsedByFills(fills: OptimizedMarketOrder[], gasSchedule: GasSchedule): number { +function getTotalGasUsedByFills(fills: OptimizedOrder[], gasSchedule: GasSchedule): number { let gasUsed = 0; for (const f of fills) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: fix me! diff --git a/test/asset-swapper/exchange_proxy_swap_quote_consumer_test.ts b/test/asset-swapper/exchange_proxy_swap_quote_consumer_test.ts index abbb7ecea..594ae5e65 100644 --- a/test/asset-swapper/exchange_proxy_swap_quote_consumer_test.ts +++ b/test/asset-swapper/exchange_proxy_swap_quote_consumer_test.ts @@ -30,7 +30,7 @@ import { Fill, NativeFillData, OptimizedLimitOrder, - OptimizedMarketOrder, + OptimizedOrder, } from '../../src/asset-swapper/types'; import { chaiSetup } from './utils/chai_setup'; @@ -172,7 +172,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => { type PlainOrder = Exclude; - function cleanOrders(orders: OptimizedMarketOrder[]): PlainOrder[] { + function cleanOrders(orders: OptimizedOrder[]): PlainOrder[] { return orders.map( (o) => _.omit( diff --git a/test/asset-swapper/quote_simulation_test.ts b/test/asset-swapper/quote_simulation_test.ts index ba005029b..870ce2530 100644 --- a/test/asset-swapper/quote_simulation_test.ts +++ b/test/asset-swapper/quote_simulation_test.ts @@ -7,10 +7,9 @@ import { MarketOperation, ERC20BridgeSource, Fill, - NativeLimitOrderFillData, - OptimizedMarketOrder, - OptimizedMarketOrderBase, + OptimizedOrder, GasSchedule, + OptimizedLimitOrder, } from '../../src/asset-swapper/types'; import { fillQuoteOrders, @@ -103,7 +102,7 @@ describe('quote_simulation tests', async () => { takerOutputFee: BigNumber; type: FillQuoteTransformerOrderType; }> = {}, - ): OptimizedMarketOrderBase { + ): OptimizedOrder { const { filledInput, side, takerInputFee, takerOutputFee, type } = _.merge( {}, { @@ -124,36 +123,74 @@ describe('quote_simulation tests', async () => { const fillableTakerAmount = side === MarketOperation.Sell ? fillableInput : fillableOutput; const takerFee = BigNumber.max(takerInputFee, takerOutputFee); - const order: OptimizedMarketOrderBase = { - source: ERC20BridgeSource.Native, - makerToken: MAKER_TOKEN, - takerToken: TAKER_TOKEN, - makerAmount: fillableMakerAmount, - takerAmount: fillableTakerAmount, - fillData: { - order: { + switch (type) { + case FillQuoteTransformerOrderType.Bridge: + throw new Error('unimplemented'); + case FillQuoteTransformerOrderType.Limit: + return { + source: ERC20BridgeSource.Native, makerToken: MAKER_TOKEN, - makerAmount, takerToken: TAKER_TOKEN, - takerAmount, - maker: NULL_ADDRESS, - taker: NULL_ADDRESS, - sender: NULL_ADDRESS, - salt: ZERO, - chainId: 1, - pool: NULL_BYTES, - verifyingContract: NULL_ADDRESS, - expiry: ZERO, - feeRecipient: NULL_ADDRESS, - takerTokenFeeAmount: takerFee, - }, - signature: { v: 1, r: NULL_BYTES, s: NULL_BYTES, signatureType: SignatureType.EthSign }, - maxTakerTokenFillAmount: fillableTakerAmount, - }, - type, - fill: createOrderFill(fillableInput, fillableOutput), - }; - return order; + makerAmount: fillableMakerAmount, + takerAmount: fillableTakerAmount, + fillData: { + order: { + makerToken: MAKER_TOKEN, + makerAmount, + takerToken: TAKER_TOKEN, + takerAmount, + maker: NULL_ADDRESS, + taker: NULL_ADDRESS, + sender: NULL_ADDRESS, + salt: ZERO, + chainId: 1, + pool: NULL_BYTES, + verifyingContract: NULL_ADDRESS, + expiry: ZERO, + feeRecipient: NULL_ADDRESS, + takerTokenFeeAmount: takerFee, + }, + signature: { v: 1, r: NULL_BYTES, s: NULL_BYTES, signatureType: SignatureType.EthSign }, + maxTakerTokenFillAmount: fillableTakerAmount, + }, + type, + fill: createOrderFill(fillableInput, fillableOutput), + }; + case FillQuoteTransformerOrderType.Rfq: + return { + source: ERC20BridgeSource.Native, + makerToken: MAKER_TOKEN, + takerToken: TAKER_TOKEN, + makerAmount: fillableMakerAmount, + takerAmount: fillableTakerAmount, + fillData: { + order: { + makerToken: MAKER_TOKEN, + makerAmount, + takerToken: TAKER_TOKEN, + takerAmount, + maker: NULL_ADDRESS, + taker: NULL_ADDRESS, + txOrigin: NULL_ADDRESS, + salt: ZERO, + chainId: 1, + pool: NULL_BYTES, + verifyingContract: NULL_ADDRESS, + expiry: ZERO, + }, + signature: { v: 1, r: NULL_BYTES, s: NULL_BYTES, signatureType: SignatureType.EthSign }, + maxTakerTokenFillAmount: fillableTakerAmount, + }, + type, + fill: createOrderFill(fillableInput, fillableOutput), + }; + case FillQuoteTransformerOrderType.Otc: + throw new Error('unimplemented'); + default: + ((_: never) => { + throw new Error('unreachable'); + })(type); + } } const nativeSourcePathId = hexUtils.random(); function createOrderFill(input: BigNumber, output: BigNumber): Fill { @@ -624,11 +661,7 @@ describe('quote_simulation tests', async () => { }); }); - function slipOrder( - order: OptimizedMarketOrderBase, - orderSlippage: number, - side: MarketOperation, - ): OptimizedMarketOrder { + function slipOrder(order: OptimizedLimitOrder, orderSlippage: number, side: MarketOperation): OptimizedLimitOrder { const makerScaling = side === MarketOperation.Sell ? 1 - orderSlippage : 1; const takerScaling = side === MarketOperation.Sell ? 1 : orderSlippage + 1; @@ -662,9 +695,7 @@ describe('quote_simulation tests', async () => { fillableOutput, side, }); - const orders = fillOrders.map((fo) => - slipOrder(fo.order as OptimizedMarketOrderBase, orderSlippage, side), - ); + const orders = fillOrders.map((fo) => slipOrder(fo.order as OptimizedLimitOrder, orderSlippage, side)); const result = simulateBestCaseFill({ orders, side, @@ -897,9 +928,7 @@ describe('quote_simulation tests', async () => { fillableInput, fillableOutput, side, - }).map((fo) => - slipOrder(fo.order as OptimizedMarketOrderBase, orderSlippage, side), - ); + }).map((fo) => slipOrder(fo.order as OptimizedLimitOrder, orderSlippage, side)); orders = [...orders.slice(1), orders[0]]; const bestCase = simulateBestCaseFill({ orders,