upgraded exchange sell with market sell
This commit is contained in:
parent
64a0080616
commit
347c6d02cf
@ -32,6 +32,8 @@ export {
|
||||
SwapQuoteExecutionOpts,
|
||||
SwapQuoteInfo,
|
||||
SwapQuoteRequestOpts,
|
||||
MarketBuySwapQuote,
|
||||
MarketSellSwapQuote,
|
||||
LiquidityForAssetData,
|
||||
LiquidityRequestOpts,
|
||||
OrdersAndFillableAmounts,
|
||||
|
@ -8,6 +8,9 @@ import { constants } from '../constants';
|
||||
import {
|
||||
CalldataInfo,
|
||||
ExchangeMarketBuySmartContractParams,
|
||||
ExchangeMarketSellSmartContractParams,
|
||||
MarketBuySwapQuote,
|
||||
MarketSellSwapQuote,
|
||||
SmartContractParamsInfo,
|
||||
SwapQuote,
|
||||
SwapQuoteConsumer,
|
||||
@ -20,7 +23,7 @@ import { assert } from '../utils/assert';
|
||||
import { swapQuoteConsumerUtils } from '../utils/swap_quote_consumer_utils';
|
||||
import { utils } from '../utils/utils';
|
||||
|
||||
export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMarketBuySmartContractParams> {
|
||||
export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMarketBuySmartContractParams | ExchangeMarketSellSmartContractParams> {
|
||||
public readonly provider: ZeroExProvider;
|
||||
public readonly networkId: number;
|
||||
|
||||
@ -44,9 +47,20 @@ export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMark
|
||||
): Promise<CalldataInfo> {
|
||||
assert.isValidSwapQuote('quote', quote);
|
||||
|
||||
const { params, to, ethAmount, methodAbi } = await this.getSmartContractParamsOrThrowAsync(quote, opts);
|
||||
const consumableQuote = (quote as any) as (MarketBuySwapQuote | MarketSellSwapQuote);
|
||||
const smartContractParamsInfo = await this.getSmartContractParamsOrThrowAsync(consumableQuote, opts);
|
||||
const { to, methodAbi, ethAmount } = smartContractParamsInfo;
|
||||
|
||||
const abiEncoder = new AbiEncoder.Method(methodAbi);
|
||||
const args = [params.orders, params.makerAssetFillAmount, params.signatures];
|
||||
|
||||
let args: any[];
|
||||
if (utils.isSwapQuoteMarketBuy(consumableQuote)) {
|
||||
const marketBuyParams = (smartContractParamsInfo.params as any) as ExchangeMarketBuySmartContractParams;
|
||||
args = [marketBuyParams.orders, marketBuyParams.makerAssetFillAmount, marketBuyParams.signatures];
|
||||
} else {
|
||||
const marketSellParams = (smartContractParamsInfo.params as any) as ExchangeMarketSellSmartContractParams;
|
||||
args = [marketSellParams.orders, marketSellParams.takerAssetFillAmount, marketSellParams.signatures];
|
||||
}
|
||||
const calldataHexString = abiEncoder.encode(args);
|
||||
return {
|
||||
calldataHexString,
|
||||
@ -59,22 +73,45 @@ export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMark
|
||||
public async getSmartContractParamsOrThrowAsync(
|
||||
quote: SwapQuote,
|
||||
opts: Partial<SwapQuoteGetOutputOpts>,
|
||||
): Promise<SmartContractParamsInfo<ExchangeMarketBuySmartContractParams>> {
|
||||
): Promise<SmartContractParamsInfo<ExchangeMarketBuySmartContractParams | ExchangeMarketSellSmartContractParams>> {
|
||||
assert.isValidSwapQuote('quote', quote);
|
||||
|
||||
const { orders, makerAssetFillAmount } = quote;
|
||||
const consumableQuote = (quote as any) as (
|
||||
| MarketBuySwapQuote
|
||||
| MarketSellSwapQuote);
|
||||
|
||||
const { orders } = consumableQuote;
|
||||
|
||||
const signatures = _.map(orders, o => o.signature);
|
||||
|
||||
const params: ExchangeMarketBuySmartContractParams = {
|
||||
orders,
|
||||
signatures,
|
||||
makerAssetFillAmount,
|
||||
};
|
||||
let params: ExchangeMarketBuySmartContractParams | ExchangeMarketSellSmartContractParams;
|
||||
let methodName: string;
|
||||
|
||||
if (utils.isSwapQuoteMarketBuy(consumableQuote)) {
|
||||
const { makerAssetFillAmount } = consumableQuote;
|
||||
|
||||
params = {
|
||||
orders,
|
||||
signatures,
|
||||
makerAssetFillAmount,
|
||||
};
|
||||
|
||||
methodName = 'marketBuyOrders';
|
||||
} else {
|
||||
const { takerAssetFillAmount } = consumableQuote;
|
||||
|
||||
params = {
|
||||
orders,
|
||||
signatures,
|
||||
takerAssetFillAmount,
|
||||
};
|
||||
|
||||
methodName = 'marketSellOrders';
|
||||
}
|
||||
|
||||
const methodAbi = utils.getMethodAbiFromContractAbi(
|
||||
this._contractWrappers.exchange.abi,
|
||||
'marketBuyOrdersNoThrow',
|
||||
methodName,
|
||||
) as MethodAbi;
|
||||
|
||||
return {
|
||||
@ -102,21 +139,41 @@ export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMark
|
||||
assert.isBigNumber('gasPrice', gasPrice);
|
||||
}
|
||||
|
||||
const { orders, makerAssetFillAmount } = quote;
|
||||
const consumableQuote = (quote as any) as (
|
||||
| MarketBuySwapQuote
|
||||
| MarketSellSwapQuote);
|
||||
|
||||
const { orders } = consumableQuote;
|
||||
|
||||
const finalTakerAddress = await swapQuoteConsumerUtils.getTakerAddressOrThrowAsync(this.provider, opts);
|
||||
|
||||
try {
|
||||
const txHash = await this._contractWrappers.exchange.marketBuyOrdersNoThrowAsync(
|
||||
orders,
|
||||
makerAssetFillAmount,
|
||||
finalTakerAddress,
|
||||
{
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
shouldValidate: true,
|
||||
},
|
||||
);
|
||||
let txHash: string;
|
||||
if (utils.isSwapQuoteMarketBuy(consumableQuote)) {
|
||||
const { makerAssetFillAmount } = consumableQuote;
|
||||
txHash = await this._contractWrappers.exchange.marketBuyOrdersNoThrowAsync(
|
||||
orders,
|
||||
makerAssetFillAmount,
|
||||
finalTakerAddress,
|
||||
{
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
shouldValidate: true,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
const { takerAssetFillAmount } = consumableQuote;
|
||||
txHash = await this._contractWrappers.exchange.marketSellOrdersNoThrowAsync(
|
||||
orders,
|
||||
takerAssetFillAmount,
|
||||
finalTakerAddress,
|
||||
{
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
shouldValidate: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
return txHash;
|
||||
} catch (err) {
|
||||
if (_.includes(err.message, ContractWrappersError.SignatureRequestDenied)) {
|
||||
|
@ -77,6 +77,12 @@ export interface ExchangeMarketBuySmartContractParams {
|
||||
signatures: string[];
|
||||
}
|
||||
|
||||
export interface ExchangeMarketSellSmartContractParams {
|
||||
orders: SignedOrder[];
|
||||
takerAssetFillAmount: BigNumber;
|
||||
signatures: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* orders: An array of objects conforming to SignedOrder. These orders can be used to cover the requested assetBuyAmount plus slippage.
|
||||
* makerAssetFillAmount: The amount of makerAsset to swap for.
|
||||
@ -101,18 +107,6 @@ export interface ForwarderMarketSellSmartContractParams extends ExchangeMarketSe
|
||||
feeRecipient: string;
|
||||
}
|
||||
|
||||
export interface ExchangeMarketBuySmartContractParams {
|
||||
orders: SignedOrder[];
|
||||
makerAssetFillAmount: BigNumber;
|
||||
signatures: string[];
|
||||
}
|
||||
|
||||
export interface ExchangeMarketSellSmartContractParams {
|
||||
orders: SignedOrder[];
|
||||
takerAssetFillAmount: BigNumber;
|
||||
signatures: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface that varying SwapQuoteConsumers adhere to (exchange consumer, router consumer, forwarder consumer, coordinator consumer)
|
||||
* getCalldataOrThrow: Get CalldataInfo to swap for tokens with provided SwapQuote. Throws if invalid SwapQuote is provided.
|
||||
@ -187,14 +181,14 @@ export interface SwapQuote {
|
||||
|
||||
export interface MarketSellSwapQuote extends SwapQuote {
|
||||
takerAssetFillAmount: BigNumber;
|
||||
bestCaseQuoteInfo: MarketSellSwapQuoteInfo;
|
||||
worstCaseQuoteInfo: MarketSellSwapQuoteInfo;
|
||||
bestCaseQuoteInfo: SwapQuoteInfo;
|
||||
worstCaseQuoteInfo: SwapQuoteInfo;
|
||||
}
|
||||
|
||||
export interface MarketBuySwapQuote extends SwapQuote {
|
||||
makerAssetFillAmount: BigNumber;
|
||||
bestCaseQuoteInfo: MarketBuySwapQuoteInfo;
|
||||
worstCaseQuoteInfo: MarketBuySwapQuoteInfo;
|
||||
bestCaseQuoteInfo: SwapQuoteInfo;
|
||||
worstCaseQuoteInfo: SwapQuoteInfo;
|
||||
}
|
||||
|
||||
export interface SwapQuoteWithAffiliateFee extends SwapQuote {
|
||||
@ -209,14 +203,8 @@ export interface SwapQuoteWithAffiliateFee extends SwapQuote {
|
||||
export interface SwapQuoteInfo {
|
||||
feeTakerTokenAmount: BigNumber;
|
||||
totalTakerTokenAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface MarketSellSwapQuoteInfo extends SwapQuoteInfo {
|
||||
makerTokenAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface MarketBuySwapQuoteInfo extends SwapQuoteInfo {
|
||||
takerTokenAmount: BigNumber;
|
||||
makerTokenAmount: BigNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,13 +42,8 @@ export const assert = {
|
||||
isValidSwapQuoteInfo(variableName: string, swapQuoteInfo: SwapQuoteInfo): void {
|
||||
sharedAssert.isBigNumber(`${variableName}.feeTakerTokenAmount`, swapQuoteInfo.feeTakerTokenAmount);
|
||||
sharedAssert.isBigNumber(`${variableName}.totalTakerTokenAmount`, swapQuoteInfo.totalTakerTokenAmount);
|
||||
if (utils.isSwapQuoteInfoMarketBuy(swapQuoteInfo)) {
|
||||
sharedAssert.isBigNumber(`${variableName}.takerTokenAmount`, swapQuoteInfo.takerTokenAmount);
|
||||
} else if (utils.isSwapQuoteInfoMarketSell(swapQuoteInfo)) {
|
||||
sharedAssert.isBigNumber(`${variableName}.takerTokenAmount`, swapQuoteInfo.makerTokenAmount);
|
||||
} else {
|
||||
throw new Error(SwapQuoteConsumerError.InvalidMarketSellOrMarketBuySwapQuote);
|
||||
}
|
||||
sharedAssert.isBigNumber(`${variableName}.takerTokenAmount`, swapQuoteInfo.takerTokenAmount);
|
||||
sharedAssert.isBigNumber(`${variableName}.takerTokenAmount`, swapQuoteInfo.makerTokenAmount);
|
||||
},
|
||||
isValidOrderProvider(variableName: string, orderFetcher: OrderProvider): void {
|
||||
sharedAssert.isFunction(`${variableName}.getOrdersAsync`, orderFetcher.getOrdersAsync);
|
||||
|
@ -6,10 +6,9 @@ import { constants } from '../constants';
|
||||
import { InsufficientAssetLiquidityError } from '../errors';
|
||||
import {
|
||||
MarketBuySwapQuote,
|
||||
MarketBuySwapQuoteInfo,
|
||||
MarketSellSwapQuote,
|
||||
MarketSellSwapQuoteInfo,
|
||||
OrdersAndFillableAmounts,
|
||||
SwapQuoteInfo,
|
||||
SwapQuoterError,
|
||||
} from '../types';
|
||||
|
||||
@ -231,19 +230,19 @@ export const swapQuoteCalculator = {
|
||||
function calculateMarketBuyQuoteInfo(
|
||||
ordersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
feeOrdersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
makerAssetBuyAmount: BigNumber,
|
||||
makerTokenAmount: BigNumber,
|
||||
isMakerAssetZrxToken: boolean,
|
||||
): MarketBuySwapQuoteInfo {
|
||||
): SwapQuoteInfo {
|
||||
// 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;
|
||||
if (isMakerAssetZrxToken) {
|
||||
takerTokenAmount = findTakerTokenAmountNeededToBuyZrx(ordersAndFillableAmounts, makerAssetBuyAmount);
|
||||
takerTokenAmount = findTakerTokenAmountNeededToBuyZrx(ordersAndFillableAmounts, makerTokenAmount);
|
||||
} else {
|
||||
// find eth and zrx amounts needed to buy
|
||||
const takerTokenAndZrxAmountToBuyAsset = findTakerTokenAndZrxAmountNeededToBuyAsset(
|
||||
ordersAndFillableAmounts,
|
||||
makerAssetBuyAmount,
|
||||
makerTokenAmount,
|
||||
);
|
||||
takerTokenAmount = takerTokenAndZrxAmountToBuyAsset[0];
|
||||
const zrxAmountToBuyAsset = takerTokenAndZrxAmountToBuyAsset[1];
|
||||
@ -256,6 +255,7 @@ function calculateMarketBuyQuoteInfo(
|
||||
// eth amount needed in total is the sum of the amount needed for the asset and the amount needed for fees
|
||||
const totalTakerTokenAmount = takerTokenAmount.plus(feeTakerTokenAmount);
|
||||
return {
|
||||
makerTokenAmount,
|
||||
takerTokenAmount,
|
||||
feeTakerTokenAmount,
|
||||
totalTakerTokenAmount,
|
||||
@ -265,22 +265,22 @@ function calculateMarketBuyQuoteInfo(
|
||||
function calculateMarketSellQuoteInfo(
|
||||
ordersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
feeOrdersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
takerAssetSellAmount: BigNumber,
|
||||
takerTokenAmount: BigNumber,
|
||||
isMakerAssetZrxToken: boolean,
|
||||
): MarketSellSwapQuoteInfo {
|
||||
): SwapQuoteInfo {
|
||||
// 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;
|
||||
if (isMakerAssetZrxToken) {
|
||||
makerTokenAmount = findZrxTokenAmountFromSellingTakerTokenAmount(
|
||||
ordersAndFillableAmounts,
|
||||
takerAssetSellAmount,
|
||||
takerTokenAmount,
|
||||
);
|
||||
} else {
|
||||
// find eth and zrx amounts needed to buy
|
||||
const takerTokenAndZrxAmountToBuyAsset = findMakerTokenAmountReceivedAndZrxAmountNeededToSellAsset(
|
||||
ordersAndFillableAmounts,
|
||||
takerAssetSellAmount,
|
||||
takerTokenAmount,
|
||||
);
|
||||
makerTokenAmount = takerTokenAndZrxAmountToBuyAsset[0];
|
||||
const zrxAmountToSellAsset = takerTokenAndZrxAmountToBuyAsset[1];
|
||||
@ -291,9 +291,10 @@ function calculateMarketSellQuoteInfo(
|
||||
const feeTakerTokenAmount = zrxTakerTokenAmount;
|
||||
|
||||
// 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);
|
||||
const totalTakerTokenAmount = takerTokenAmount.plus(feeTakerTokenAmount);
|
||||
return {
|
||||
makerTokenAmount,
|
||||
takerTokenAmount,
|
||||
feeTakerTokenAmount,
|
||||
totalTakerTokenAmount,
|
||||
};
|
||||
|
@ -6,11 +6,8 @@ import * as _ from 'lodash';
|
||||
import { constants } from '../constants';
|
||||
import {
|
||||
MarketBuySwapQuote,
|
||||
MarketBuySwapQuoteInfo,
|
||||
MarketSellSwapQuote,
|
||||
MarketSellSwapQuoteInfo,
|
||||
SwapQuote,
|
||||
SwapQuoteInfo,
|
||||
} from '../types';
|
||||
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
@ -39,10 +36,4 @@ export const utils = {
|
||||
isSwapQuoteMarketSell(quote: SwapQuote): quote is MarketSellSwapQuote {
|
||||
return (quote as MarketBuySwapQuote).makerAssetFillAmount !== undefined;
|
||||
},
|
||||
isSwapQuoteInfoMarketBuy(quote: SwapQuoteInfo): quote is MarketBuySwapQuoteInfo {
|
||||
return (quote as MarketBuySwapQuoteInfo).takerTokenAmount !== undefined;
|
||||
},
|
||||
isSwapQuoteInfoMarketSell(quote: SwapQuoteInfo): quote is MarketSellSwapQuoteInfo {
|
||||
return (quote as MarketSellSwapQuoteInfo).makerTokenAmount !== undefined;
|
||||
},
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user