refactored for market sell + buy
This commit is contained in:
@@ -5,7 +5,6 @@ import {
|
||||
ForwarderSwapQuoteExecutionOpts,
|
||||
ForwarderSwapQuoteGetOutputOpts,
|
||||
OrdersAndFillableAmounts,
|
||||
SwapQuoteOperation,
|
||||
SwapQuoteRequestOpts,
|
||||
SwapQuoterOpts,
|
||||
} from './types';
|
||||
@@ -30,7 +29,6 @@ const DEFAULT_FORWARDER_SWAP_QUOTE_EXECUTE_OPTS: ForwarderSwapQuoteExecutionOpts
|
||||
const DEFAULT_SWAP_QUOTE_REQUEST_OPTS: SwapQuoteRequestOpts = {
|
||||
shouldForceOrderRefresh: false,
|
||||
slippagePercentage: 0.2, // 20% slippage protection,
|
||||
operation: SwapQuoteOperation.MarketBuy,
|
||||
};
|
||||
|
||||
const EMPTY_ORDERS_AND_FILLABLE_AMOUNTS: OrdersAndFillableAmounts = {
|
||||
|
||||
@@ -12,13 +12,14 @@ import { StandardRelayerAPIOrderProvider } from './order_providers/standard_rela
|
||||
import {
|
||||
LiquidityForAssetData,
|
||||
LiquidityRequestOpts,
|
||||
MarketBuySwapQuote,
|
||||
MarketSellSwapQuote,
|
||||
OrderProvider,
|
||||
OrdersAndFillableAmounts,
|
||||
SwapQuote,
|
||||
SwapQuoteRequestOpts,
|
||||
SwapQuoterError,
|
||||
SwapQuoterOpts,
|
||||
SwapQuoteOperation,
|
||||
} from './types';
|
||||
|
||||
import { assert } from './utils/assert';
|
||||
@@ -126,25 +127,25 @@ export class SwapQuoter {
|
||||
* You can then pass the `SwapQuote` to a `SwapQuoteConsumer` to execute a buy, or process SwapQuote for on-chain consumption.
|
||||
* @param makerAssetData The makerAssetData of the desired asset to swap for (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param takerAssetData The takerAssetData of the asset to swap makerAssetData for (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param makerAssetSwapAmount The amount of maker asset to swap for.
|
||||
* @param takerAssetSellAmount The amount of maker asset to swap for.
|
||||
* @param options Options for the request. See type definition for more information.
|
||||
*
|
||||
* @return An object that conforms to SwapQuote that satisfies the request. See type definition for more information.
|
||||
*/
|
||||
public async getSwapQuoteAsync(
|
||||
public async getMarketSellSwapQuoteAsync(
|
||||
makerAssetData: string,
|
||||
takerAssetData: string,
|
||||
assetSwapAmount: BigNumber,
|
||||
takerAssetSellAmount: BigNumber,
|
||||
options: Partial<SwapQuoteRequestOpts> = {},
|
||||
): Promise<SwapQuote> {
|
||||
const { shouldForceOrderRefresh, slippagePercentage, operation } = _.merge(
|
||||
): Promise<MarketSellSwapQuote> {
|
||||
const { shouldForceOrderRefresh, slippagePercentage } = _.merge(
|
||||
{},
|
||||
constants.DEFAULT_SWAP_QUOTE_REQUEST_OPTS,
|
||||
options,
|
||||
);
|
||||
assert.isString('makerAssetData', makerAssetData);
|
||||
assert.isString('takerAssetData', takerAssetData);
|
||||
assert.isBigNumber('assetSwapAmount', assetSwapAmount);
|
||||
assert.isBigNumber('takerAssetSellAmount', takerAssetSellAmount);
|
||||
assert.isBoolean('shouldForceOrderRefresh', shouldForceOrderRefresh);
|
||||
assert.isNumber('slippagePercentage', slippagePercentage);
|
||||
const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow();
|
||||
@@ -165,24 +166,68 @@ export class SwapQuoter {
|
||||
}: For makerAssetdata ${makerAssetData} and takerAssetdata ${takerAssetData}`,
|
||||
);
|
||||
}
|
||||
let swapQuote: SwapQuote;
|
||||
if (operation === SwapQuoteOperation.MarketBuy) {
|
||||
swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||
ordersAndFillableAmounts,
|
||||
feeOrdersAndFillableAmounts,
|
||||
assetSwapAmount,
|
||||
takerAssetSellAmount,
|
||||
slippagePercentage,
|
||||
isMakerAssetZrxToken,
|
||||
);
|
||||
} else {
|
||||
swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||
ordersAndFillableAmounts,
|
||||
feeOrdersAndFillableAmounts,
|
||||
assetSwapAmount,
|
||||
slippagePercentage,
|
||||
isMakerAssetZrxToken,
|
||||
return swapQuote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a `SwapQuote` containing all information relevant to fulfilling a swap between a desired ERC20 token address and ERC20 owned by a provided address.
|
||||
* You can then pass the `SwapQuote` to a `SwapQuoteConsumer` to execute a buy, or process SwapQuote for on-chain consumption.
|
||||
* @param makerAssetData The makerAssetData of the desired asset to swap for (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param takerAssetData The takerAssetData of the asset to swap makerAssetData for (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param makerAssetSwapAmount The amount of maker asset to swap for.
|
||||
* @param options Options for the request. See type definition for more information.
|
||||
*
|
||||
* @return An object that conforms to SwapQuote that satisfies the request. See type definition for more information.
|
||||
*/
|
||||
public async getMarketBuySwapQuoteAsync(
|
||||
makerAssetData: string,
|
||||
takerAssetData: string,
|
||||
makerAssetBuyAmount: BigNumber,
|
||||
options: Partial<SwapQuoteRequestOpts> = {},
|
||||
): Promise<MarketBuySwapQuote> {
|
||||
const { shouldForceOrderRefresh, slippagePercentage } = _.merge(
|
||||
{},
|
||||
constants.DEFAULT_SWAP_QUOTE_REQUEST_OPTS,
|
||||
options,
|
||||
);
|
||||
assert.isString('makerAssetData', makerAssetData);
|
||||
assert.isString('takerAssetData', takerAssetData);
|
||||
assert.isBigNumber('makerAssetBuyAmount', makerAssetBuyAmount);
|
||||
assert.isBoolean('shouldForceOrderRefresh', shouldForceOrderRefresh);
|
||||
assert.isNumber('slippagePercentage', slippagePercentage);
|
||||
const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow();
|
||||
const isMakerAssetZrxToken = makerAssetData === zrxTokenAssetData;
|
||||
// get the relevant orders for the makerAsset and fees
|
||||
// if the requested assetData is ZRX, don't get the fee info
|
||||
const [ordersAndFillableAmounts, feeOrdersAndFillableAmounts] = await Promise.all([
|
||||
this.getOrdersAndFillableAmountsAsync(makerAssetData, takerAssetData, shouldForceOrderRefresh),
|
||||
isMakerAssetZrxToken
|
||||
? Promise.resolve(constants.EMPTY_ORDERS_AND_FILLABLE_AMOUNTS)
|
||||
: this.getOrdersAndFillableAmountsAsync(zrxTokenAssetData, takerAssetData, shouldForceOrderRefresh),
|
||||
shouldForceOrderRefresh,
|
||||
]);
|
||||
if (ordersAndFillableAmounts.orders.length === 0) {
|
||||
throw new Error(
|
||||
`${
|
||||
SwapQuoterError.AssetUnavailable
|
||||
}: For makerAssetdata ${makerAssetData} and takerAssetdata ${takerAssetData}`,
|
||||
);
|
||||
}
|
||||
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||
ordersAndFillableAmounts,
|
||||
feeOrdersAndFillableAmounts,
|
||||
makerAssetBuyAmount,
|
||||
slippagePercentage,
|
||||
isMakerAssetZrxToken,
|
||||
);
|
||||
|
||||
return swapQuote;
|
||||
}
|
||||
/**
|
||||
@@ -195,18 +240,43 @@ export class SwapQuoter {
|
||||
*
|
||||
* @return An object that conforms to SwapQuote that satisfies the request. See type definition for more information.
|
||||
*/
|
||||
public async getSwapQuoteForERC20TokenAddressAsync(
|
||||
public async getMarketBuySwapQuoteForERC20TokenAddressAsync(
|
||||
makerTokenAddress: string,
|
||||
takerTokenAddress: string,
|
||||
assetSwapAmount: BigNumber,
|
||||
makerAssetBuyAmount: BigNumber,
|
||||
options: Partial<SwapQuoteRequestOpts> = {},
|
||||
): Promise<SwapQuote> {
|
||||
assert.isETHAddressHex('makerTokenAddress', makerTokenAddress);
|
||||
assert.isETHAddressHex('takerTokenAddress', takerTokenAddress);
|
||||
assert.isBigNumber('assetSwapAmount', assetSwapAmount);
|
||||
assert.isBigNumber('makerAssetBuyAmount', makerAssetBuyAmount);
|
||||
const makerAssetData = assetDataUtils.encodeERC20AssetData(makerTokenAddress);
|
||||
const takerAssetData = assetDataUtils.encodeERC20AssetData(takerTokenAddress);
|
||||
const swapQuote = this.getSwapQuoteAsync(makerAssetData, takerAssetData, assetSwapAmount, options);
|
||||
const swapQuote = this.getMarketBuySwapQuoteAsync(makerAssetData, takerAssetData, makerAssetBuyAmount, options);
|
||||
return swapQuote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a `SwapQuote` containing all information relevant to fulfilling a swap between a desired ERC20 token address and ERC20 owned by a provided address.
|
||||
* You can then pass the `SwapQuote` to a `SwapQuoteConsumer` to execute a buy, or process SwapQuote for on-chain consumption.
|
||||
* @param makerAssetData The makerAssetData of the desired asset to swap for (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param takerAssetData The takerAssetData of the asset to swap makerAssetData for (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param makerAssetSwapAmount The amount of maker asset to swap for.
|
||||
* @param options Options for the request. See type definition for more information.
|
||||
*
|
||||
* @return An object that conforms to SwapQuote that satisfies the request. See type definition for more information.
|
||||
*/
|
||||
public async getMarketSellSwapQuoteForERC20TokenAddressAsync(
|
||||
makerTokenAddress: string,
|
||||
takerTokenAddress: string,
|
||||
takerAssetSellAmount: BigNumber,
|
||||
options: Partial<SwapQuoteRequestOpts> = {},
|
||||
): Promise<SwapQuote> {
|
||||
assert.isETHAddressHex('makerTokenAddress', makerTokenAddress);
|
||||
assert.isETHAddressHex('takerTokenAddress', takerTokenAddress);
|
||||
assert.isBigNumber('takerAssetSellAmount', takerAssetSellAmount);
|
||||
const makerAssetData = assetDataUtils.encodeERC20AssetData(makerTokenAddress);
|
||||
const takerAssetData = assetDataUtils.encodeERC20AssetData(takerTokenAddress);
|
||||
const swapQuote = this.getMarketSellSwapQuoteAsync(makerAssetData, takerAssetData, takerAssetSellAmount, options);
|
||||
return swapQuote;
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -154,11 +154,6 @@ export interface ForwarderSwapQuoteGetOutputOpts extends SwapQuoteGetOutputOpts
|
||||
*/
|
||||
export interface ForwarderSwapQuoteExecutionOpts extends ForwarderSwapQuoteGetOutputOpts, SwapQuoteExecutionOpts {}
|
||||
|
||||
export enum SwapQuoteOperation {
|
||||
MarketSell = 'MARKET_SELL',
|
||||
MarketBuy = 'MARKET_BUY',
|
||||
}
|
||||
|
||||
/**
|
||||
* takerAssetData: String that represents a specific taker asset (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* makerAssetData: String that represents a specific maker asset (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
@@ -171,13 +166,22 @@ export enum SwapQuoteOperation {
|
||||
export interface SwapQuote {
|
||||
takerAssetData: string;
|
||||
makerAssetData: string;
|
||||
takerAssetFillAmount?: BigNumber;
|
||||
makerAssetFillAmount?: BigNumber;
|
||||
orders: SignedOrder[];
|
||||
feeOrders: SignedOrder[];
|
||||
bestCaseQuoteInfo: SwapQuoteInfo;
|
||||
worstCaseQuoteInfo: SwapQuoteInfo;
|
||||
operation: SwapQuoteOperation;
|
||||
}
|
||||
|
||||
export interface MarketSellSwapQuote extends SwapQuote {
|
||||
takerAssetFillAmount: BigNumber;
|
||||
bestCaseQuoteInfo: MarketSellSwapQuoteInfo;
|
||||
worstCaseQuoteInfo: MarketSellSwapQuoteInfo;
|
||||
}
|
||||
|
||||
export interface MarketBuySwapQuote extends SwapQuote {
|
||||
makerAssetFillAmount: BigNumber;
|
||||
bestCaseQuoteInfo: MarketBuySwapQuoteInfo;
|
||||
worstCaseQuoteInfo: MarketBuySwapQuoteInfo;
|
||||
}
|
||||
|
||||
export interface SwapQuoteWithAffiliateFee extends SwapQuote {
|
||||
@@ -190,12 +194,18 @@ export interface SwapQuoteWithAffiliateFee extends SwapQuote {
|
||||
* totalEthAmount: The total amount of eth required to complete the buy (filling orders, feeOrders, and paying affiliate fee).
|
||||
*/
|
||||
export interface SwapQuoteInfo {
|
||||
takerTokenAmount: BigNumber;
|
||||
makerTokenAmount: BigNumber;
|
||||
feeTakerTokenAmount: BigNumber;
|
||||
totalTakerTokenAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface MarketSellSwapQuoteInfo extends SwapQuoteInfo {
|
||||
makerTokenAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface MarketBuySwapQuoteInfo extends SwapQuoteInfo {
|
||||
takerTokenAmount: BigNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* shouldForceOrderRefresh: If set to true, new orders and state will be fetched instead of waiting for the next orderRefreshIntervalMs. Defaults to false.
|
||||
* slippagePercentage: The percentage buffer to add to account for slippage. Affects max ETH price estimates. Defaults to 0.2 (20%).
|
||||
@@ -203,7 +213,6 @@ export interface SwapQuoteInfo {
|
||||
export interface SwapQuoteRequestOpts {
|
||||
shouldForceOrderRefresh: boolean;
|
||||
slippagePercentage: number;
|
||||
operation: SwapQuoteOperation;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as _ from 'lodash';
|
||||
|
||||
import { constants } from '../constants';
|
||||
import { InsufficientAssetLiquidityError } from '../errors';
|
||||
import { OrdersAndFillableAmounts, SwapQuote, SwapQuoteInfo, SwapQuoteOperation, SwapQuoterError } from '../types';
|
||||
import { MarketBuySwapQuote, MarketBuySwapQuoteInfo, MarketSellSwapQuote, MarketSellSwapQuoteInfo, OrdersAndFillableAmounts, SwapQuoterError } from '../types';
|
||||
|
||||
// Calculates a swap quote for orders
|
||||
export const swapQuoteCalculator = {
|
||||
@@ -14,7 +14,7 @@ export const swapQuoteCalculator = {
|
||||
takerAssetFillAmount: BigNumber,
|
||||
slippagePercentage: number,
|
||||
isMakerAssetZrxToken: boolean,
|
||||
): SwapQuote {
|
||||
): MarketSellSwapQuote {
|
||||
const orders = ordersAndFillableAmounts.orders;
|
||||
const remainingFillableMakerAssetAmounts = ordersAndFillableAmounts.remainingFillableMakerAssetAmounts;
|
||||
const remainingFillableTakerAssetAmounts = remainingFillableMakerAssetAmounts.map((makerAssetAmount: BigNumber, index: number) => {
|
||||
@@ -112,7 +112,6 @@ export const swapQuoteCalculator = {
|
||||
feeOrders: resultFeeOrders,
|
||||
bestCaseQuoteInfo,
|
||||
worstCaseQuoteInfo,
|
||||
operation: SwapQuoteOperation.MarketBuy,
|
||||
};
|
||||
},
|
||||
calculateMarketBuySwapQuote(
|
||||
@@ -121,7 +120,7 @@ export const swapQuoteCalculator = {
|
||||
makerAssetFillAmount: BigNumber,
|
||||
slippagePercentage: number,
|
||||
isMakerAssetZrxToken: boolean,
|
||||
): SwapQuote {
|
||||
): MarketBuySwapQuote {
|
||||
const orders = ordersAndFillableAmounts.orders;
|
||||
const remainingFillableMakerAssetAmounts = ordersAndFillableAmounts.remainingFillableMakerAssetAmounts;
|
||||
const feeOrders = feeOrdersAndFillableAmounts.orders;
|
||||
@@ -213,7 +212,6 @@ export const swapQuoteCalculator = {
|
||||
feeOrders: resultFeeOrders,
|
||||
bestCaseQuoteInfo,
|
||||
worstCaseQuoteInfo,
|
||||
operation: SwapQuoteOperation.MarketBuy,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -223,7 +221,7 @@ function calculateMarketBuyQuoteInfo(
|
||||
feeOrdersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
makerAssetBuyAmount: BigNumber,
|
||||
isMakerAssetZrxToken: boolean,
|
||||
): SwapQuoteInfo {
|
||||
): MarketBuySwapQuoteInfo {
|
||||
// find the total eth and zrx needed to buy assetAmount from the resultOrders from left to right
|
||||
let takerTokenAmount = constants.ZERO_AMOUNT;
|
||||
let zrxTakerTokenAmount = constants.ZERO_AMOUNT;
|
||||
@@ -247,7 +245,6 @@ function calculateMarketBuyQuoteInfo(
|
||||
const totalTakerTokenAmount = takerTokenAmount.plus(feeTakerTokenAmount);
|
||||
return {
|
||||
takerTokenAmount,
|
||||
makerTokenAmount: makerAssetBuyAmount,
|
||||
feeTakerTokenAmount,
|
||||
totalTakerTokenAmount,
|
||||
};
|
||||
@@ -258,7 +255,7 @@ function calculateMarketSellQuoteInfo(
|
||||
feeOrdersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
takerAssetSellAmount: BigNumber,
|
||||
isMakerAssetZrxToken: boolean,
|
||||
): SwapQuoteInfo {
|
||||
): MarketSellSwapQuoteInfo {
|
||||
// find the total eth and zrx needed to buy assetAmount from the resultOrders from left to right
|
||||
let makerTokenAmount = constants.ZERO_AMOUNT;
|
||||
let zrxTakerTokenAmount = constants.ZERO_AMOUNT;
|
||||
@@ -281,7 +278,6 @@ function calculateMarketSellQuoteInfo(
|
||||
// eth amount needed in total is the sum of the amount needed for the asset and the amount needed for fees
|
||||
const totalTakerTokenAmount = takerAssetSellAmount.plus(feeTakerTokenAmount);
|
||||
return {
|
||||
takerTokenAmount: takerAssetSellAmount,
|
||||
makerTokenAmount,
|
||||
feeTakerTokenAmount,
|
||||
totalTakerTokenAmount,
|
||||
|
||||
Reference in New Issue
Block a user