linting issues

This commit is contained in:
David Sun
2019-07-02 12:03:07 -07:00
parent 4d4b4e0f2b
commit 6a8197a4e8
4 changed files with 141 additions and 3 deletions

View File

@@ -18,7 +18,7 @@ export {
export { SignedOrder } from '@0x/types';
export { BigNumber } from '@0x/utils';
export { ForwarderSwapQuoteConsumer } from './quote_consumers/forwarder_swap_quote_consumer';
export { DynamicSwapQuoteConsumer as SwapQuoteConsumer } from './quote_consumers/dynamic_swap_quote_consumer';
export { SwapQuoter } from './swap_quoter';
export { InsufficientAssetLiquidityError } from './errors';
@@ -29,7 +29,8 @@ export {
SwapQuoterError,
SwapQuoterOpts,
SwapQuote,
SwapQuoteExecutionOpts,
DynamicSwapQuoteGetOutputOpts as SwapQuoteGetOutputOpts,
DynamicSwapQuoteExecutionOpts as SwapQuoteExecutionOpts,
SwapQuoteInfo,
SwapQuoteRequestOpts,
MarketBuySwapQuote,

View File

@@ -0,0 +1,104 @@
import { ContractWrappers } from '@0x/contract-wrappers';
import { BigNumber, providerUtils } from '@0x/utils';
import { SupportedProvider, ZeroExProvider } from '@0x/web3-wrapper';
import * as _ from 'lodash';
import { constants } from '../constants';
import {
CalldataInfo,
DynamicSwapQuoteExecutionOpts,
DynamicSwapQuoteGetOutputOpts,
ExchangeMarketBuySmartContractParams,
ExchangeMarketSellSmartContractParams,
ForwarderMarketBuySmartContractParams,
ForwarderMarketSellSmartContractParams,
SmartContractParamsInfo,
SwapQuote,
SwapQuoteConsumer,
SwapQuoteConsumerOpts,
} from '../types';
import { assert } from '../utils/assert';
import { assetDataUtils } from '../utils/asset_data_utils';
import { swapQuoteConsumerUtils } from '../utils/swap_quote_consumer_utils';
import { ExchangeSwapQuoteConsumer } from './exchange_swap_quote_consumer';
import { ForwarderSwapQuoteConsumer } from './forwarder_swap_quote_consumer';
type SmartContractParams = ExchangeMarketBuySmartContractParams | ExchangeMarketSellSmartContractParams | ForwarderMarketBuySmartContractParams | ForwarderMarketSellSmartContractParams;
type ValidSwapQuoteConsumer = ExchangeSwapQuoteConsumer | ForwarderSwapQuoteConsumer;
export class DynamicSwapQuoteConsumer
implements SwapQuoteConsumer<SmartContractParams> {
public readonly provider: ZeroExProvider;
public readonly networkId: number;
private readonly _contractWrappers: ContractWrappers;
private readonly _exchangeConsumer: ExchangeSwapQuoteConsumer;
private readonly _forwarderConsumer: ForwarderSwapQuoteConsumer;
constructor(supportedProvider: SupportedProvider, options: Partial<SwapQuoteConsumerOpts> = {}) {
const { networkId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options);
assert.isNumber('networkId', networkId);
const provider = providerUtils.standardizeOrThrow(supportedProvider);
this.provider = provider;
this.networkId = networkId;
this._contractWrappers = new ContractWrappers(this.provider, {
networkId,
});
this._exchangeConsumer = new ExchangeSwapQuoteConsumer(supportedProvider, options);
this._forwarderConsumer = new ForwarderSwapQuoteConsumer(supportedProvider, options);
}
public async getCalldataOrThrowAsync(
quote: SwapQuote,
opts: Partial<DynamicSwapQuoteGetOutputOpts>,
): Promise<CalldataInfo> {
assert.isValidSwapQuote('quote', quote);
const consumer = await this._getConsumerForSwapQuoteAsync(quote, opts);
return consumer.getCalldataOrThrowAsync(quote, opts);
}
public async getSmartContractParamsOrThrowAsync(
quote: SwapQuote,
opts: Partial<DynamicSwapQuoteGetOutputOpts>,
): Promise<SmartContractParamsInfo<SmartContractParams>> {
assert.isValidSwapQuote('quote', quote);
const consumer = await this._getConsumerForSwapQuoteAsync(quote, opts);
return consumer.getSmartContractParamsOrThrowAsync(quote, opts);
}
public async executeSwapQuoteOrThrowAsync(
quote: SwapQuote,
opts: Partial<DynamicSwapQuoteExecutionOpts>,
): Promise<string> {
assert.isValidSwapQuote('quote', quote);
const consumer = await this._getConsumerForSwapQuoteAsync(quote, opts);
return consumer.executeSwapQuoteOrThrowAsync(quote, opts);
}
private async _getConsumerForSwapQuoteAsync(quote: SwapQuote, opts: Partial<DynamicSwapQuoteGetOutputOpts>): Promise<ValidSwapQuoteConsumer> {
const wethAssetData = assetDataUtils.getEtherTokenAssetData(this._contractWrappers);
if (swapQuoteConsumerUtils.isValidForwarderSwapQuote(quote, wethAssetData)) {
if (opts.takerAddress !== undefined) {
assert.isETHAddressHex('takerAddress', opts.takerAddress);
}
const ethAmount = opts.ethAmount || quote.worstCaseQuoteInfo.totalTakerTokenAmount;
const takerAddress = await swapQuoteConsumerUtils.getTakerAddressOrThrowAsync(this.provider, opts);
const takerEthAndWethBalance = await swapQuoteConsumerUtils.getEthAndWethBalanceAsync(this.provider, this._contractWrappers, takerAddress);
// TODO(david): when considering if there is enough Eth balance, should account for gas costs.
const isEnoughEthAndWethBalance = _.map(takerEthAndWethBalance, (balance: BigNumber) => balance.isGreaterThanOrEqualTo(ethAmount));
if (isEnoughEthAndWethBalance[1]) { // should be more gas efficient to use exchange consumer, so if possible use it.
return this._exchangeConsumer;
} else if (isEnoughEthAndWethBalance[0] && !isEnoughEthAndWethBalance[1]) {
return this._forwarderConsumer;
}
// Note: Should we default to a consumer if takerAddress has not enough Eth or Weth?
return this._forwarderConsumer;
} else {
return this._exchangeConsumer;
}
}
}

View File

@@ -148,6 +148,20 @@ export interface SwapQuoteExecutionOpts extends SwapQuoteGetOutputOpts {
gasPrice?: BigNumber;
}
/**
* feePercentage: percentage (up to 5%) of the taker asset paid to feeRecipient
* feeRecipient: address of the receiver of the feePercentage of taker asset
* ethAmount: The amount of eth (in Wei) sent to the forwarder contract.
*/
export interface DynamicSwapQuoteGetOutputOpts extends SwapQuoteGetOutputOpts {
takerAddress?: string;
}
/**
* Represents the options for executing a swap quote with ForwarderSwapQuoteConusmer
*/
export interface DynamicSwapQuoteExecutionOpts extends DynamicSwapQuoteGetOutputOpts, SwapQuoteExecutionOpts {}
/**
* feePercentage: percentage (up to 5%) of the taker asset paid to feeRecipient
* feeRecipient: address of the receiver of the feePercentage of taker asset

View File

@@ -1,7 +1,10 @@
import { ContractWrappers } from '@0x/contract-wrappers';
import { SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { SupportedProvider, Web3Wrapper } from '@0x/web3-wrapper';
import * as _ from 'lodash';
import { SwapQuoteConsumerError, SwapQuoteExecutionOpts } from '../types';
import { SwapQuote, SwapQuoteConsumerError, SwapQuoteExecutionOpts } from '../types';
export const swapQuoteConsumerUtils = {
async getTakerAddressOrThrowAsync(
@@ -21,4 +24,20 @@ export const swapQuoteConsumerUtils = {
}
}
},
async getEthAndWethBalanceAsync(provider: SupportedProvider, contractWrappers: ContractWrappers, takerAddress: string): Promise<[BigNumber, BigNumber]> {
const web3Wrapper = new Web3Wrapper(provider);
const wethAddress = contractWrappers.forwarder.etherTokenAddress;
const ethBalance = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
const wethBalance = await contractWrappers.erc20Token.getBalanceAsync(wethAddress, takerAddress);
return [ethBalance, wethBalance];
},
isValidForwarderSwapQuote(swapQuote: SwapQuote, wethAssetData: string): boolean {
return swapQuoteConsumerUtils.isValidForwarderSignedOrders(swapQuote.orders, wethAssetData) && swapQuoteConsumerUtils.isValidForwarderSignedOrders(swapQuote.feeOrders, wethAssetData);
},
isValidForwarderSignedOrders(orders: SignedOrder[], wethAssetData: string): boolean {
return _.every(orders, order => swapQuoteConsumerUtils.isValidForwarderSignedOrder(order, wethAssetData));
},
isValidForwarderSignedOrder(order: SignedOrder, wethAssetData: string): boolean {
return order.takerAssetData === wethAssetData;
},
};