add forwarder logic for market sell
This commit is contained in:
parent
288a7d4cea
commit
64a0080616
@ -8,8 +8,11 @@ import { constants } from '../constants';
|
|||||||
import {
|
import {
|
||||||
CalldataInfo,
|
CalldataInfo,
|
||||||
ForwarderMarketBuySmartContractParams,
|
ForwarderMarketBuySmartContractParams,
|
||||||
|
ForwarderMarketSellSmartContractParams,
|
||||||
ForwarderSwapQuoteExecutionOpts,
|
ForwarderSwapQuoteExecutionOpts,
|
||||||
ForwarderSwapQuoteGetOutputOpts,
|
ForwarderSwapQuoteGetOutputOpts,
|
||||||
|
MarketBuySwapQuote,
|
||||||
|
MarketSellSwapQuote,
|
||||||
SmartContractParamsInfo,
|
SmartContractParamsInfo,
|
||||||
SwapQuote,
|
SwapQuote,
|
||||||
SwapQuoteConsumer,
|
SwapQuoteConsumer,
|
||||||
@ -22,7 +25,8 @@ import { assetDataUtils } from '../utils/asset_data_utils';
|
|||||||
import { swapQuoteConsumerUtils } from '../utils/swap_quote_consumer_utils';
|
import { swapQuoteConsumerUtils } from '../utils/swap_quote_consumer_utils';
|
||||||
import { utils } from '../utils/utils';
|
import { utils } from '../utils/utils';
|
||||||
|
|
||||||
export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumer<ForwarderMarketBuySmartContractParams> {
|
export class ForwarderSwapQuoteConsumer
|
||||||
|
implements SwapQuoteConsumer<ForwarderMarketBuySmartContractParams | ForwarderMarketSellSmartContractParams> {
|
||||||
public readonly provider: ZeroExProvider;
|
public readonly provider: ZeroExProvider;
|
||||||
public readonly networkId: number;
|
public readonly networkId: number;
|
||||||
|
|
||||||
@ -51,17 +55,35 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumer<ForwarderMa
|
|||||||
): Promise<CalldataInfo> {
|
): Promise<CalldataInfo> {
|
||||||
assert.isValidForwarderSwapQuote('quote', quote, this._getEtherTokenAssetDataOrThrow());
|
assert.isValidForwarderSwapQuote('quote', quote, this._getEtherTokenAssetDataOrThrow());
|
||||||
|
|
||||||
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 abiEncoder = new AbiEncoder.Method(methodAbi);
|
||||||
const args = [
|
|
||||||
params.orders,
|
let args: any[];
|
||||||
params.makerAssetFillAmount,
|
if (utils.isSwapQuoteMarketBuy(consumableQuote)) {
|
||||||
params.signatures,
|
const marketBuyParams = (smartContractParamsInfo.params as any) as ForwarderMarketBuySmartContractParams;
|
||||||
params.feeOrders,
|
args = [
|
||||||
params.feeSignatures,
|
marketBuyParams.orders,
|
||||||
params.feePercentage,
|
marketBuyParams.makerAssetFillAmount,
|
||||||
params.feeRecipient,
|
marketBuyParams.signatures,
|
||||||
];
|
marketBuyParams.feeOrders,
|
||||||
|
marketBuyParams.feeSignatures,
|
||||||
|
marketBuyParams.feePercentage,
|
||||||
|
marketBuyParams.feeRecipient,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
const marketSellParams = (smartContractParamsInfo.params as any) as ForwarderMarketSellSmartContractParams;
|
||||||
|
args = [
|
||||||
|
marketSellParams.orders,
|
||||||
|
marketSellParams.signatures,
|
||||||
|
marketSellParams.feeOrders,
|
||||||
|
marketSellParams.feeSignatures,
|
||||||
|
marketSellParams.feePercentage,
|
||||||
|
marketSellParams.feeRecipient,
|
||||||
|
];
|
||||||
|
}
|
||||||
const calldataHexString = abiEncoder.encode(args);
|
const calldataHexString = abiEncoder.encode(args);
|
||||||
return {
|
return {
|
||||||
calldataHexString,
|
calldataHexString,
|
||||||
@ -79,7 +101,9 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumer<ForwarderMa
|
|||||||
public async getSmartContractParamsOrThrowAsync(
|
public async getSmartContractParamsOrThrowAsync(
|
||||||
quote: SwapQuote,
|
quote: SwapQuote,
|
||||||
opts: Partial<ForwarderSwapQuoteGetOutputOpts>,
|
opts: Partial<ForwarderSwapQuoteGetOutputOpts>,
|
||||||
): Promise<SmartContractParamsInfo<ForwarderMarketBuySmartContractParams>> {
|
): Promise<
|
||||||
|
SmartContractParamsInfo<ForwarderMarketBuySmartContractParams | ForwarderMarketSellSmartContractParams>
|
||||||
|
> {
|
||||||
assert.isValidForwarderSwapQuote('quote', quote, this._getEtherTokenAssetDataOrThrow());
|
assert.isValidForwarderSwapQuote('quote', quote, this._getEtherTokenAssetDataOrThrow());
|
||||||
|
|
||||||
const { ethAmount, feeRecipient, feePercentage: unFormattedFeePercentage } = _.merge(
|
const { ethAmount, feeRecipient, feePercentage: unFormattedFeePercentage } = _.merge(
|
||||||
@ -99,26 +123,51 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumer<ForwarderMa
|
|||||||
unFormattedFeePercentage,
|
unFormattedFeePercentage,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { orders, feeOrders, makerAssetFillAmount, worstCaseQuoteInfo } = swapQuoteWithAffiliateFee;
|
const consumableQuoteWithAffiliateFee = (swapQuoteWithAffiliateFee as any) as (
|
||||||
|
| MarketBuySwapQuote
|
||||||
|
| MarketSellSwapQuote);
|
||||||
|
|
||||||
|
const { orders, feeOrders, worstCaseQuoteInfo } = swapQuoteWithAffiliateFee;
|
||||||
|
|
||||||
const signatures = _.map(orders, o => o.signature);
|
const signatures = _.map(orders, o => o.signature);
|
||||||
const feeSignatures = _.map(feeOrders, o => o.signature);
|
const feeSignatures = _.map(feeOrders, o => o.signature);
|
||||||
|
|
||||||
const feePercentage = utils.numberPercentageToEtherTokenAmountPercentage(unFormattedFeePercentage);
|
const feePercentage = utils.numberPercentageToEtherTokenAmountPercentage(unFormattedFeePercentage);
|
||||||
|
|
||||||
const params: ForwarderMarketBuySmartContractParams = {
|
let params: ForwarderMarketBuySmartContractParams | ForwarderMarketSellSmartContractParams;
|
||||||
orders,
|
let methodName: string;
|
||||||
makerAssetFillAmount,
|
|
||||||
signatures,
|
|
||||||
feeOrders,
|
|
||||||
feeSignatures,
|
|
||||||
feePercentage,
|
|
||||||
feeRecipient,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
if (utils.isSwapQuoteMarketBuy(consumableQuoteWithAffiliateFee)) {
|
||||||
|
const { makerAssetFillAmount } = consumableQuoteWithAffiliateFee;
|
||||||
|
|
||||||
|
params = {
|
||||||
|
orders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
signatures,
|
||||||
|
feeOrders,
|
||||||
|
feeSignatures,
|
||||||
|
feePercentage,
|
||||||
|
feeRecipient,
|
||||||
|
};
|
||||||
|
|
||||||
|
methodName = 'marketBuyOrdersWithEth';
|
||||||
|
} else {
|
||||||
|
const { takerAssetFillAmount } = consumableQuoteWithAffiliateFee;
|
||||||
|
|
||||||
|
params = {
|
||||||
|
orders,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signatures,
|
||||||
|
feeOrders,
|
||||||
|
feeSignatures,
|
||||||
|
feePercentage,
|
||||||
|
feeRecipient,
|
||||||
|
};
|
||||||
|
methodName = 'marketSellOrdersWithEth';
|
||||||
|
}
|
||||||
const methodAbi = utils.getMethodAbiFromContractAbi(
|
const methodAbi = utils.getMethodAbiFromContractAbi(
|
||||||
this._contractWrappers.forwarder.abi,
|
this._contractWrappers.forwarder.abi,
|
||||||
'marketBuyOrdersWithEth',
|
methodName,
|
||||||
) as MethodAbi;
|
) as MethodAbi;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -163,25 +212,47 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumer<ForwarderMa
|
|||||||
|
|
||||||
const swapQuoteWithAffiliateFee = affiliateFeeUtils.getSwapQuoteWithAffiliateFee(quote, feePercentage);
|
const swapQuoteWithAffiliateFee = affiliateFeeUtils.getSwapQuoteWithAffiliateFee(quote, feePercentage);
|
||||||
|
|
||||||
const { orders, feeOrders, makerAssetFillAmount, worstCaseQuoteInfo } = swapQuoteWithAffiliateFee;
|
const consumableQuoteWithAffiliateFee = (swapQuoteWithAffiliateFee as any) as (
|
||||||
|
| MarketBuySwapQuote
|
||||||
|
| MarketSellSwapQuote);
|
||||||
|
|
||||||
|
const { orders, feeOrders, worstCaseQuoteInfo } = consumableQuoteWithAffiliateFee;
|
||||||
|
|
||||||
const finalTakerAddress = await swapQuoteConsumerUtils.getTakerAddressOrThrowAsync(this.provider, opts);
|
const finalTakerAddress = await swapQuoteConsumerUtils.getTakerAddressOrThrowAsync(this.provider, opts);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const txHash = await this._contractWrappers.forwarder.marketBuyOrdersWithEthAsync(
|
let txHash: string;
|
||||||
orders,
|
if (utils.isSwapQuoteMarketBuy(consumableQuoteWithAffiliateFee)) {
|
||||||
makerAssetFillAmount,
|
const { makerAssetFillAmount } = consumableQuoteWithAffiliateFee;
|
||||||
finalTakerAddress,
|
txHash = await this._contractWrappers.forwarder.marketBuyOrdersWithEthAsync(
|
||||||
ethAmount || worstCaseQuoteInfo.totalTakerTokenAmount,
|
orders,
|
||||||
feeOrders,
|
makerAssetFillAmount,
|
||||||
feePercentage,
|
finalTakerAddress,
|
||||||
feeRecipient,
|
ethAmount || worstCaseQuoteInfo.totalTakerTokenAmount,
|
||||||
{
|
feeOrders,
|
||||||
gasLimit,
|
feePercentage,
|
||||||
gasPrice,
|
feeRecipient,
|
||||||
shouldValidate: true,
|
{
|
||||||
},
|
gasLimit,
|
||||||
);
|
gasPrice,
|
||||||
|
shouldValidate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
txHash = await this._contractWrappers.forwarder.marketSellOrdersWithEthAsync(
|
||||||
|
orders,
|
||||||
|
finalTakerAddress,
|
||||||
|
ethAmount || worstCaseQuoteInfo.totalTakerTokenAmount,
|
||||||
|
feeOrders,
|
||||||
|
feePercentage,
|
||||||
|
feeRecipient,
|
||||||
|
{
|
||||||
|
gasLimit,
|
||||||
|
gasPrice,
|
||||||
|
shouldValidate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
return txHash;
|
return txHash;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (_.includes(err.message, ContractWrappersError.SignatureRequestDenied)) {
|
if (_.includes(err.message, ContractWrappersError.SignatureRequestDenied)) {
|
||||||
|
@ -167,12 +167,12 @@ export class SwapQuoter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
|
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
feeOrdersAndFillableAmounts,
|
feeOrdersAndFillableAmounts,
|
||||||
takerAssetSellAmount,
|
takerAssetSellAmount,
|
||||||
slippagePercentage,
|
slippagePercentage,
|
||||||
isMakerAssetZrxToken,
|
isMakerAssetZrxToken,
|
||||||
);
|
);
|
||||||
return swapQuote;
|
return swapQuote;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,12 +221,12 @@ export class SwapQuoter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
|
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
feeOrdersAndFillableAmounts,
|
feeOrdersAndFillableAmounts,
|
||||||
makerAssetBuyAmount,
|
makerAssetBuyAmount,
|
||||||
slippagePercentage,
|
slippagePercentage,
|
||||||
isMakerAssetZrxToken,
|
isMakerAssetZrxToken,
|
||||||
);
|
);
|
||||||
|
|
||||||
return swapQuote;
|
return swapQuote;
|
||||||
}
|
}
|
||||||
@ -276,7 +276,12 @@ export class SwapQuoter {
|
|||||||
assert.isBigNumber('takerAssetSellAmount', takerAssetSellAmount);
|
assert.isBigNumber('takerAssetSellAmount', takerAssetSellAmount);
|
||||||
const makerAssetData = assetDataUtils.encodeERC20AssetData(makerTokenAddress);
|
const makerAssetData = assetDataUtils.encodeERC20AssetData(makerTokenAddress);
|
||||||
const takerAssetData = assetDataUtils.encodeERC20AssetData(takerTokenAddress);
|
const takerAssetData = assetDataUtils.encodeERC20AssetData(takerTokenAddress);
|
||||||
const swapQuote = this.getMarketSellSwapQuoteAsync(makerAssetData, takerAssetData, takerAssetSellAmount, options);
|
const swapQuote = this.getMarketSellSwapQuoteAsync(
|
||||||
|
makerAssetData,
|
||||||
|
takerAssetData,
|
||||||
|
takerAssetSellAmount,
|
||||||
|
options,
|
||||||
|
);
|
||||||
return swapQuote;
|
return swapQuote;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -94,12 +94,25 @@ export interface ForwarderMarketBuySmartContractParams extends ExchangeMarketBuy
|
|||||||
feeRecipient: string;
|
feeRecipient: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ForwarderMarketSellSmartContractParams extends ExchangeMarketSellSmartContractParams {
|
||||||
|
feeOrders: SignedOrder[];
|
||||||
|
feeSignatures: string[];
|
||||||
|
feePercentage: BigNumber;
|
||||||
|
feeRecipient: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ExchangeMarketBuySmartContractParams {
|
export interface ExchangeMarketBuySmartContractParams {
|
||||||
orders: SignedOrder[];
|
orders: SignedOrder[];
|
||||||
makerAssetFillAmount: BigNumber;
|
makerAssetFillAmount: BigNumber;
|
||||||
signatures: string[];
|
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)
|
* 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.
|
* getCalldataOrThrow: Get CalldataInfo to swap for tokens with provided SwapQuote. Throws if invalid SwapQuote is provided.
|
||||||
@ -236,6 +249,7 @@ export interface SwapQuoterOpts {
|
|||||||
* Possible error messages thrown by an SwapQuoterConsumer instance or associated static methods.
|
* Possible error messages thrown by an SwapQuoterConsumer instance or associated static methods.
|
||||||
*/
|
*/
|
||||||
export enum SwapQuoteConsumerError {
|
export enum SwapQuoteConsumerError {
|
||||||
|
InvalidMarketSellOrMarketBuySwapQuote = 'INVALID_MARKET_BUY_SELL_SWAP_QUOTE',
|
||||||
InvalidForwarderSwapQuote = 'INVALID_FORWARDER_SWAP_QUOTE_PROVIDED',
|
InvalidForwarderSwapQuote = 'INVALID_FORWARDER_SWAP_QUOTE_PROVIDED',
|
||||||
NoAddressAvailable = 'NO_ADDRESS_AVAILABLE',
|
NoAddressAvailable = 'NO_ADDRESS_AVAILABLE',
|
||||||
SignatureRequestDenied = 'SIGNATURE_REQUEST_DENIED',
|
SignatureRequestDenied = 'SIGNATURE_REQUEST_DENIED',
|
||||||
|
@ -3,7 +3,8 @@ import { schemas } from '@0x/json-schemas';
|
|||||||
import { SignedOrder } from '@0x/types';
|
import { SignedOrder } from '@0x/types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { OrderProvider, OrderProviderRequest, SwapQuote, SwapQuoteInfo } from '../types';
|
import { OrderProvider, OrderProviderRequest, SwapQuote, SwapQuoteConsumerError, SwapQuoteInfo } from '../types';
|
||||||
|
import { utils } from '../utils/utils';
|
||||||
|
|
||||||
export const assert = {
|
export const assert = {
|
||||||
...sharedAssert,
|
...sharedAssert,
|
||||||
@ -14,7 +15,13 @@ export const assert = {
|
|||||||
sharedAssert.doesConformToSchema(`${variableName}.feeOrders`, swapQuote.feeOrders, schemas.signedOrdersSchema);
|
sharedAssert.doesConformToSchema(`${variableName}.feeOrders`, swapQuote.feeOrders, schemas.signedOrdersSchema);
|
||||||
assert.isValidSwapQuoteInfo(`${variableName}.bestCaseQuoteInfo`, swapQuote.bestCaseQuoteInfo);
|
assert.isValidSwapQuoteInfo(`${variableName}.bestCaseQuoteInfo`, swapQuote.bestCaseQuoteInfo);
|
||||||
assert.isValidSwapQuoteInfo(`${variableName}.worstCaseQuoteInfo`, swapQuote.worstCaseQuoteInfo);
|
assert.isValidSwapQuoteInfo(`${variableName}.worstCaseQuoteInfo`, swapQuote.worstCaseQuoteInfo);
|
||||||
sharedAssert.isBigNumber(`${variableName}.makerAssetFillAmount`, swapQuote.makerAssetFillAmount);
|
if (utils.isSwapQuoteMarketBuy(swapQuote)) {
|
||||||
|
sharedAssert.isBigNumber(`${variableName}.makerAssetFillAmount`, swapQuote.makerAssetFillAmount);
|
||||||
|
} else if (utils.isSwapQuoteMarketSell(swapQuote)) {
|
||||||
|
sharedAssert.isBigNumber(`${variableName}.takerAssetFillAmount`, swapQuote.takerAssetFillAmount);
|
||||||
|
} else {
|
||||||
|
throw new Error(SwapQuoteConsumerError.InvalidMarketSellOrMarketBuySwapQuote);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
isValidForwarderSwapQuote(variableName: string, swapQuote: SwapQuote, wethAssetData: string): void {
|
isValidForwarderSwapQuote(variableName: string, swapQuote: SwapQuote, wethAssetData: string): void {
|
||||||
assert.isValidSwapQuote(variableName, swapQuote);
|
assert.isValidSwapQuote(variableName, swapQuote);
|
||||||
@ -33,9 +40,15 @@ export const assert = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
isValidSwapQuoteInfo(variableName: string, swapQuoteInfo: SwapQuoteInfo): void {
|
isValidSwapQuoteInfo(variableName: string, swapQuoteInfo: SwapQuoteInfo): void {
|
||||||
sharedAssert.isBigNumber(`${variableName}.takerTokenAmount`, swapQuoteInfo.takerTokenAmount);
|
|
||||||
sharedAssert.isBigNumber(`${variableName}.feeTakerTokenAmount`, swapQuoteInfo.feeTakerTokenAmount);
|
sharedAssert.isBigNumber(`${variableName}.feeTakerTokenAmount`, swapQuoteInfo.feeTakerTokenAmount);
|
||||||
sharedAssert.isBigNumber(`${variableName}.totalTakerTokenAmount`, swapQuoteInfo.totalTakerTokenAmount);
|
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);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
isValidOrderProvider(variableName: string, orderFetcher: OrderProvider): void {
|
isValidOrderProvider(variableName: string, orderFetcher: OrderProvider): void {
|
||||||
sharedAssert.isFunction(`${variableName}.getOrdersAsync`, orderFetcher.getOrdersAsync);
|
sharedAssert.isFunction(`${variableName}.getOrdersAsync`, orderFetcher.getOrdersAsync);
|
||||||
|
@ -4,7 +4,14 @@ import * as _ from 'lodash';
|
|||||||
|
|
||||||
import { constants } from '../constants';
|
import { constants } from '../constants';
|
||||||
import { InsufficientAssetLiquidityError } from '../errors';
|
import { InsufficientAssetLiquidityError } from '../errors';
|
||||||
import { MarketBuySwapQuote, MarketBuySwapQuoteInfo, MarketSellSwapQuote, MarketSellSwapQuoteInfo, OrdersAndFillableAmounts, SwapQuoterError } from '../types';
|
import {
|
||||||
|
MarketBuySwapQuote,
|
||||||
|
MarketBuySwapQuoteInfo,
|
||||||
|
MarketSellSwapQuote,
|
||||||
|
MarketSellSwapQuoteInfo,
|
||||||
|
OrdersAndFillableAmounts,
|
||||||
|
SwapQuoterError,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
// Calculates a swap quote for orders
|
// Calculates a swap quote for orders
|
||||||
export const swapQuoteCalculator = {
|
export const swapQuoteCalculator = {
|
||||||
@ -17,9 +24,11 @@ export const swapQuoteCalculator = {
|
|||||||
): MarketSellSwapQuote {
|
): MarketSellSwapQuote {
|
||||||
const orders = ordersAndFillableAmounts.orders;
|
const orders = ordersAndFillableAmounts.orders;
|
||||||
const remainingFillableMakerAssetAmounts = ordersAndFillableAmounts.remainingFillableMakerAssetAmounts;
|
const remainingFillableMakerAssetAmounts = ordersAndFillableAmounts.remainingFillableMakerAssetAmounts;
|
||||||
const remainingFillableTakerAssetAmounts = remainingFillableMakerAssetAmounts.map((makerAssetAmount: BigNumber, index: number) => {
|
const remainingFillableTakerAssetAmounts = remainingFillableMakerAssetAmounts.map(
|
||||||
return orderCalculationUtils.getTakerFillAmount(orders[index], makerAssetAmount);
|
(makerAssetAmount: BigNumber, index: number) => {
|
||||||
});
|
return orderCalculationUtils.getTakerFillAmount(orders[index], makerAssetAmount);
|
||||||
|
},
|
||||||
|
);
|
||||||
const feeOrders = feeOrdersAndFillableAmounts.orders;
|
const feeOrders = feeOrdersAndFillableAmounts.orders;
|
||||||
const remainingFillableFeeAmounts = feeOrdersAndFillableAmounts.remainingFillableMakerAssetAmounts;
|
const remainingFillableFeeAmounts = feeOrdersAndFillableAmounts.remainingFillableMakerAssetAmounts;
|
||||||
const slippageBufferAmount = takerAssetFillAmount.multipliedBy(slippagePercentage).integerValue();
|
const slippageBufferAmount = takerAssetFillAmount.multipliedBy(slippagePercentage).integerValue();
|
||||||
@ -32,9 +41,12 @@ export const swapQuoteCalculator = {
|
|||||||
remainingFillableTakerAssetAmounts,
|
remainingFillableTakerAssetAmounts,
|
||||||
slippageBufferAmount,
|
slippageBufferAmount,
|
||||||
});
|
});
|
||||||
const ordersRemainingFillableMakerAssetAmounts = _.map(ordersRemainingFillableTakerAssetAmounts, (takerAssetAmount: BigNumber, index: number) => {
|
const ordersRemainingFillableMakerAssetAmounts = _.map(
|
||||||
return orderCalculationUtils.getMakerFillAmount(resultOrders[index], takerAssetAmount);
|
ordersRemainingFillableTakerAssetAmounts,
|
||||||
});
|
(takerAssetAmount: BigNumber, index: number) => {
|
||||||
|
return orderCalculationUtils.getMakerFillAmount(resultOrders[index], takerAssetAmount);
|
||||||
|
},
|
||||||
|
);
|
||||||
// if we do not have enough orders to cover the desired assetBuyAmount, throw
|
// if we do not have enough orders to cover the desired assetBuyAmount, throw
|
||||||
if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) {
|
if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) {
|
||||||
// We needed the amount they requested to buy, plus the amount for slippage
|
// We needed the amount they requested to buy, plus the amount for slippage
|
||||||
@ -260,7 +272,10 @@ function calculateMarketSellQuoteInfo(
|
|||||||
let makerTokenAmount = constants.ZERO_AMOUNT;
|
let makerTokenAmount = constants.ZERO_AMOUNT;
|
||||||
let zrxTakerTokenAmount = constants.ZERO_AMOUNT;
|
let zrxTakerTokenAmount = constants.ZERO_AMOUNT;
|
||||||
if (isMakerAssetZrxToken) {
|
if (isMakerAssetZrxToken) {
|
||||||
makerTokenAmount = findZrxTokenAmountFromSellingTakerTokenAmount(ordersAndFillableAmounts, takerAssetSellAmount);
|
makerTokenAmount = findZrxTokenAmountFromSellingTakerTokenAmount(
|
||||||
|
ordersAndFillableAmounts,
|
||||||
|
takerAssetSellAmount,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// find eth and zrx amounts needed to buy
|
// find eth and zrx amounts needed to buy
|
||||||
const takerTokenAndZrxAmountToBuyAsset = findMakerTokenAmountReceivedAndZrxAmountNeededToSellAsset(
|
const takerTokenAndZrxAmountToBuyAsset = findMakerTokenAmountReceivedAndZrxAmountNeededToSellAsset(
|
||||||
@ -304,7 +319,10 @@ function findZrxTokenAmountFromSellingTakerTokenAmount(
|
|||||||
(acc, order, index) => {
|
(acc, order, index) => {
|
||||||
const { totalZrxTokenAmount, remainingTakerAssetFillAmount } = acc;
|
const { totalZrxTokenAmount, remainingTakerAssetFillAmount } = acc;
|
||||||
const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index];
|
const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index];
|
||||||
const remainingFillableTakerAssetAmount = orderCalculationUtils.getTakerFillAmount(order, remainingFillableMakerAssetAmount);
|
const remainingFillableTakerAssetAmount = orderCalculationUtils.getTakerFillAmount(
|
||||||
|
order,
|
||||||
|
remainingFillableMakerAssetAmount,
|
||||||
|
);
|
||||||
const takerFillAmount = BigNumber.min(remainingTakerAssetFillAmount, remainingFillableTakerAssetAmount);
|
const takerFillAmount = BigNumber.min(remainingTakerAssetFillAmount, remainingFillableTakerAssetAmount);
|
||||||
const makerFillAmount = orderCalculationUtils.getMakerFillAmount(order, takerFillAmount);
|
const makerFillAmount = orderCalculationUtils.getMakerFillAmount(order, takerFillAmount);
|
||||||
const feeAmount = orderCalculationUtils.getTakerFeeAmount(order, takerFillAmount);
|
const feeAmount = orderCalculationUtils.getTakerFeeAmount(order, takerFillAmount);
|
||||||
@ -400,7 +418,10 @@ function findMakerTokenAmountReceivedAndZrxAmountNeededToSellAsset(
|
|||||||
(acc, order, index) => {
|
(acc, order, index) => {
|
||||||
const { totalMakerTokenAmount, totalZrxAmount, remainingTakerAssetFillAmount } = acc;
|
const { totalMakerTokenAmount, totalZrxAmount, remainingTakerAssetFillAmount } = acc;
|
||||||
const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index];
|
const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index];
|
||||||
const remainingFillableTakerAssetAmount = orderCalculationUtils.getTakerFillAmount(order, remainingFillableMakerAssetAmount);
|
const remainingFillableTakerAssetAmount = orderCalculationUtils.getTakerFillAmount(
|
||||||
|
order,
|
||||||
|
remainingFillableMakerAssetAmount,
|
||||||
|
);
|
||||||
const takerFillAmount = BigNumber.min(acc.remainingTakerAssetFillAmount, remainingFillableTakerAssetAmount);
|
const takerFillAmount = BigNumber.min(acc.remainingTakerAssetFillAmount, remainingFillableTakerAssetAmount);
|
||||||
const makerFillAmount = orderCalculationUtils.getMakerFillAmount(order, takerFillAmount);
|
const makerFillAmount = orderCalculationUtils.getMakerFillAmount(order, takerFillAmount);
|
||||||
const takerFeeAmount = orderCalculationUtils.getTakerFeeAmount(order, takerFillAmount);
|
const takerFeeAmount = orderCalculationUtils.getTakerFeeAmount(order, takerFillAmount);
|
||||||
|
@ -4,6 +4,14 @@ import { AbiDefinition, ContractAbi, MethodAbi } from 'ethereum-types';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { constants } from '../constants';
|
import { constants } from '../constants';
|
||||||
|
import {
|
||||||
|
MarketBuySwapQuote,
|
||||||
|
MarketBuySwapQuoteInfo,
|
||||||
|
MarketSellSwapQuote,
|
||||||
|
MarketSellSwapQuoteInfo,
|
||||||
|
SwapQuote,
|
||||||
|
SwapQuoteInfo,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
// tslint:disable:no-unnecessary-type-assertion
|
// tslint:disable:no-unnecessary-type-assertion
|
||||||
export const utils = {
|
export const utils = {
|
||||||
@ -25,4 +33,16 @@ export const utils = {
|
|||||||
},
|
},
|
||||||
) as MethodAbi | undefined;
|
) as MethodAbi | undefined;
|
||||||
},
|
},
|
||||||
|
isSwapQuoteMarketBuy(quote: SwapQuote): quote is MarketBuySwapQuote {
|
||||||
|
return (quote as MarketSellSwapQuote).takerAssetFillAmount !== undefined;
|
||||||
|
},
|
||||||
|
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;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -5,9 +5,7 @@ import * as _ from 'lodash';
|
|||||||
|
|
||||||
import { assert } from './assert';
|
import { assert } from './assert';
|
||||||
import { constants } from './constants';
|
import { constants } from './constants';
|
||||||
import {
|
import { orderCalculationUtils } from './order_calculation_utils';
|
||||||
orderCalculationUtils,
|
|
||||||
} from './order_calculation_utils';
|
|
||||||
import {
|
import {
|
||||||
FeeOrdersAndRemainingFeeAmount,
|
FeeOrdersAndRemainingFeeAmount,
|
||||||
FindFeeOrdersThatCoverFeesForTargetOrdersOpts,
|
FindFeeOrdersThatCoverFeesForTargetOrdersOpts,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user