refactored sampler operations into a single external file

This commit is contained in:
Daniel Pyrathon 2020-03-02 10:06:43 -08:00
parent 82b0f85258
commit 82de5adbe9
13 changed files with 1534 additions and 1479 deletions

View File

@ -144,11 +144,13 @@ export class SwapQuoter {
* @return An instance of SwapQuoter
*/
constructor(supportedProvider: SupportedProvider, orderbook: Orderbook, options: Partial<SwapQuoterOpts> = {}) {
const { chainId, expiryBufferMs, permittedOrderFeeTypes, samplerGasLimit, liquidityProviderRegistryAddress } = _.merge(
{},
constants.DEFAULT_SWAP_QUOTER_OPTS,
options,
);
const {
chainId,
expiryBufferMs,
permittedOrderFeeTypes,
samplerGasLimit,
liquidityProviderRegistryAddress,
} = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options);
const provider = providerUtils.standardizeOrThrow(supportedProvider);
assert.isValidOrderbook('orderbook', orderbook);
assert.isNumber('chainId', chainId);

View File

@ -98,7 +98,9 @@ export class CreateOrderUtils {
return this._contractAddress.curveBridge;
case ERC20BridgeSource.LiquidityProvider:
if (liquidityPoolAddress === undefined) {
throw new Error('Cannot create a LiquidityProvider order without a LiquidityProvider pool address.');
throw new Error(
'Cannot create a LiquidityProvider order without a LiquidityProvider pool address.',
);
}
assert.isETHAddressHex('liquidityPoolAddress', liquidityPoolAddress);
return liquidityPoolAddress;

View File

@ -73,13 +73,24 @@ export class MarketOperationUtils {
...opts,
};
const [makerToken, takerToken] = getOrderTokens(nativeOrders[0]);
const [fillableAmounts, liquidityPoolAddress, ethToMakerAssetRate, dexQuotes] = await this._sampler.executeAsync(
const [
fillableAmounts,
liquidityPoolAddress,
ethToMakerAssetRate,
dexQuotes,
] = await this._sampler.executeAsync(
DexOrderSampler.ops.getOrderFillableTakerAmounts(nativeOrders),
DexOrderSampler.ops.getLiquidityProviderFromRegistry(this._liquidityProviderRegistry, takerToken, makerToken),
DexOrderSampler.ops.getLiquidityProviderFromRegistry(
this._liquidityProviderRegistry,
takerToken,
makerToken,
),
makerToken.toLowerCase() === this._wethAddress.toLowerCase()
? DexOrderSampler.ops.constant(new BigNumber(1))
: DexOrderSampler.ops.getMedianSellRate(
difference(FEE_QUOTE_SOURCES, _opts.excludedSources).concat(this._liquidityPoolSourceIfAvailable()),
difference(FEE_QUOTE_SOURCES, _opts.excludedSources).concat(
this._liquidityPoolSourceIfAvailable(),
),
makerToken,
this._wethAddress,
ONE_ETHER,
@ -160,13 +171,24 @@ export class MarketOperationUtils {
...opts,
};
const [makerToken, takerToken] = getOrderTokens(nativeOrders[0]);
const [fillableAmounts, liquidityPoolAddress, ethToTakerAssetRate, dexQuotes] = await this._sampler.executeAsync(
const [
fillableAmounts,
liquidityPoolAddress,
ethToTakerAssetRate,
dexQuotes,
] = await this._sampler.executeAsync(
DexOrderSampler.ops.getOrderFillableMakerAmounts(nativeOrders),
DexOrderSampler.ops.getLiquidityProviderFromRegistry(this._liquidityProviderRegistry, takerToken, makerToken),
DexOrderSampler.ops.getLiquidityProviderFromRegistry(
this._liquidityProviderRegistry,
takerToken,
makerToken,
),
takerToken.toLowerCase() === this._wethAddress.toLowerCase()
? DexOrderSampler.ops.constant(new BigNumber(1))
: DexOrderSampler.ops.getMedianSellRate(
difference(FEE_QUOTE_SOURCES, _opts.excludedSources).concat(this._liquidityPoolSourceIfAvailable()),
difference(FEE_QUOTE_SOURCES, _opts.excludedSources).concat(
this._liquidityPoolSourceIfAvailable(),
),
takerToken,
this._wethAddress,
ONE_ETHER,

View File

@ -1,10 +1,7 @@
import { IERC20BridgeSamplerContract } from '@0x/contract-wrappers';
import { SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { constants } from '../../constants';
import { DexSample, ERC20BridgeSource } from './types';
import { samplerOperations } from './sampler_operations';
/**
* A composable operation the be run in `DexOrderSampler.executeAsync()`.
@ -14,369 +11,6 @@ export interface BatchedOperation<TResult> {
handleCallResultsAsync(contract: IERC20BridgeSamplerContract, callResults: string): Promise<TResult>;
}
/**
* Composable operations that can be batched in a single transaction,
* for use with `DexOrderSampler.executeAsync()`.
*/
const samplerOperations = {
getOrderFillableTakerAmounts(orders: SignedOrder[]): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.getOrderFillableTakerAssetAmounts(orders, orders.map(o => o.signature))
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('getOrderFillableTakerAssetAmounts', callResults);
},
};
},
getOrderFillableMakerAmounts(orders: SignedOrder[]): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.getOrderFillableMakerAssetAmounts(orders, orders.map(o => o.signature))
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('getOrderFillableMakerAssetAmounts', callResults);
},
};
},
getKyberSellQuotes(
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromKyberNetwork(takerToken, makerToken, takerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromKyberNetwork', callResults);
},
};
},
getUniswapSellQuotes(
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromUniswap(takerToken, makerToken, takerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromUniswap', callResults);
},
};
},
getLiquidityProviderSellQuotes(
liquidityProviderRegistryAddress: string,
takerToken: string,
makerToken: string,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromLiquidityProviderRegistry(
liquidityProviderRegistryAddress,
takerToken,
makerToken,
takerFillAmounts,
)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>(
'sampleSellsFromLiquidityProviderRegistry',
callResults,
);
},
};
},
getLiquidityProviderBuyQuotes(
liquidityProviderRegistryAddress: string,
takerToken: string,
makerToken: string,
makerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleBuysFromLiquidityProviderRegistry(
liquidityProviderRegistryAddress,
takerToken,
makerToken,
makerFillAmounts,
)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>(
'sampleBuysFromLiquidityProviderRegistry',
callResults,
);
},
};
},
getEth2DaiSellQuotes(
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromEth2Dai(takerToken, makerToken, takerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromEth2Dai', callResults);
},
};
},
getCurveSellQuotes(
curveAddress: string,
fromTokenIdx: number,
toTokenIdx: number,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromCurve(
curveAddress,
new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx),
takerFillAmounts,
)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromCurve', callResults);
},
};
},
getUniswapBuyQuotes(
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleBuysFromUniswap(takerToken, makerToken, makerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromUniswap', callResults);
},
};
},
getEth2DaiBuyQuotes(
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleBuysFromEth2Dai(takerToken, makerToken, makerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromEth2Dai', callResults);
},
};
},
getMedianSellRate(
sources: ERC20BridgeSource[],
makerToken: string,
takerToken: string,
takerFillAmount: BigNumber,
liquidityProviderRegistryAddress?: string | undefined,
): BatchedOperation<BigNumber> {
const getSellQuotes = samplerOperations.getSellQuotes(
sources,
makerToken,
takerToken,
[takerFillAmount],
liquidityProviderRegistryAddress,
);
return {
encodeCall: contract => {
const subCalls = [getSellQuotes.encodeCall(contract)];
return contract.batchCall(subCalls).getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
const rawSubCallResults = contract.getABIDecodedReturnData<string[]>('batchCall', callResults);
const samples = await getSellQuotes.handleCallResultsAsync(contract, rawSubCallResults[0]);
if (samples.length === 0) {
return new BigNumber(0);
}
const flatSortedSamples = samples
.reduce((acc, v) => acc.concat(...v))
.sort((a, b) => a.output.comparedTo(b.output));
if (flatSortedSamples.length === 0) {
return new BigNumber(0);
}
const medianSample = flatSortedSamples[Math.floor(flatSortedSamples.length / 2)];
return medianSample.output.div(medianSample.input);
},
};
},
constant<T>(result: T): BatchedOperation<T> {
return {
encodeCall: contract => {
return '0x';
},
handleCallResultsAsync: async (contract, callResults) => {
return result;
},
};
},
getLiquidityProviderFromRegistry(
registryAddress: string,
takerToken: string,
makerToken: string,
): BatchedOperation<string> {
return {
encodeCall: contract => {
return contract
.getLiquidityProviderFromRegistry(registryAddress, takerToken, makerToken)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<string>('getLiquidityProviderFromRegistry', callResults);
},
};
},
getSellQuotes(
sources: ERC20BridgeSource[],
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
liquidityProviderRegistryAddress?: string | undefined,
): BatchedOperation<DexSample[][]> {
const subOps = sources
.map(source => {
let batchedOperation;
if (source === ERC20BridgeSource.Eth2Dai) {
batchedOperation = samplerOperations.getEth2DaiSellQuotes(makerToken, takerToken, takerFillAmounts);
} else if (source === ERC20BridgeSource.Uniswap) {
batchedOperation = samplerOperations.getUniswapSellQuotes(makerToken, takerToken, takerFillAmounts);
} else if (source === ERC20BridgeSource.Kyber) {
batchedOperation = samplerOperations.getKyberSellQuotes(makerToken, takerToken, takerFillAmounts);
} else if (
source === ERC20BridgeSource.CurveUsdcDai ||
source === ERC20BridgeSource.CurveUsdcDaiUsdt ||
source === ERC20BridgeSource.CurveUsdcDaiUsdtTusd
) {
const { curveAddress, tokens } = constants.DEFAULT_CURVE_OPTS[source];
const fromTokenIdx = tokens.indexOf(takerToken);
const toTokenIdx = tokens.indexOf(makerToken);
if (fromTokenIdx !== -1 && toTokenIdx !== -1) {
batchedOperation = samplerOperations.getCurveSellQuotes(
curveAddress,
fromTokenIdx,
toTokenIdx,
takerFillAmounts,
);
}
} else if (source === ERC20BridgeSource.LiquidityProvider) {
if (liquidityProviderRegistryAddress === undefined) {
throw new Error(
'Cannot sample liquidity from a LiquidityProvider liquidity pool, if a registry is not provided.',
);
}
batchedOperation = samplerOperations.getLiquidityProviderSellQuotes(
liquidityProviderRegistryAddress,
takerToken,
makerToken,
takerFillAmounts,
);
} else {
throw new Error(`Unsupported sell sample source: ${source}`);
}
return { batchedOperation, source };
})
.filter(op => op.batchedOperation) as Array<{
batchedOperation: BatchedOperation<BigNumber[]>;
source: ERC20BridgeSource;
}>;
return {
encodeCall: contract => {
const subCalls = subOps.map(op => op.batchedOperation.encodeCall(contract));
return contract.batchCall(subCalls).getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
const rawSubCallResults = contract.getABIDecodedReturnData<string[]>('batchCall', callResults);
const samples = await Promise.all(
subOps.map(async (op, i) =>
op.batchedOperation.handleCallResultsAsync(contract, rawSubCallResults[i]),
),
);
return subOps.map((op, i) => {
return samples[i].map((output, j) => ({
source: op.source,
output,
input: takerFillAmounts[j],
}));
});
},
};
},
getBuyQuotes(
sources: ERC20BridgeSource[],
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
liquidityProviderRegistryAddress?: string | undefined,
): BatchedOperation<DexSample[][]> {
const subOps = sources.map(source => {
if (source === ERC20BridgeSource.Eth2Dai) {
return samplerOperations.getEth2DaiBuyQuotes(makerToken, takerToken, makerFillAmounts);
} else if (source === ERC20BridgeSource.Uniswap) {
return samplerOperations.getUniswapBuyQuotes(makerToken, takerToken, makerFillAmounts);
} else if (source === ERC20BridgeSource.LiquidityProvider) {
if (liquidityProviderRegistryAddress === undefined) {
throw new Error(
'Cannot sample liquidity from a LiquidityProvider liquidity pool, if a registry is not provided.',
);
}
return samplerOperations.getLiquidityProviderBuyQuotes(liquidityProviderRegistryAddress, takerToken, makerToken, makerFillAmounts);
} else {
throw new Error(`Unsupported buy sample source: ${source}`);
}
});
return {
encodeCall: contract => {
const subCalls = subOps.map(op => op.encodeCall(contract));
return contract.batchCall(subCalls).getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
const rawSubCallResults = contract.getABIDecodedReturnData<string[]>('batchCall', callResults);
const samples = await Promise.all(
subOps.map(async (op, i) => op.handleCallResultsAsync(contract, rawSubCallResults[i])),
);
return sources.map((source, i) => {
return samples[i].map((output, j) => ({
source,
output,
input: makerFillAmounts[j],
}));
});
},
};
},
};
/**
* Generate sample amounts up to `maxFillAmount`.
*/

View File

@ -0,0 +1,374 @@
import { constants } from 'zlib';
import { BigNumber, ERC20BridgeSource, SignedOrder } from '../..';
import { BatchedOperation } from './sampler';
import { DexSample } from './types';
/**
* Composable operations that can be batched in a single transaction,
* for use with `DexOrderSampler.executeAsync()`.
*/
export const samplerOperations = {
getOrderFillableTakerAmounts(orders: SignedOrder[]): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.getOrderFillableTakerAssetAmounts(orders, orders.map(o => o.signature))
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('getOrderFillableTakerAssetAmounts', callResults);
},
};
},
getOrderFillableMakerAmounts(orders: SignedOrder[]): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.getOrderFillableMakerAssetAmounts(orders, orders.map(o => o.signature))
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('getOrderFillableMakerAssetAmounts', callResults);
},
};
},
getKyberSellQuotes(
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromKyberNetwork(takerToken, makerToken, takerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromKyberNetwork', callResults);
},
};
},
getUniswapSellQuotes(
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromUniswap(takerToken, makerToken, takerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromUniswap', callResults);
},
};
},
getLiquidityProviderSellQuotes(
liquidityProviderRegistryAddress: string,
takerToken: string,
makerToken: string,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromLiquidityProviderRegistry(
liquidityProviderRegistryAddress,
takerToken,
makerToken,
takerFillAmounts,
)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>(
'sampleSellsFromLiquidityProviderRegistry',
callResults,
);
},
};
},
getLiquidityProviderBuyQuotes(
liquidityProviderRegistryAddress: string,
takerToken: string,
makerToken: string,
makerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleBuysFromLiquidityProviderRegistry(
liquidityProviderRegistryAddress,
takerToken,
makerToken,
makerFillAmounts,
)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>(
'sampleBuysFromLiquidityProviderRegistry',
callResults,
);
},
};
},
getEth2DaiSellQuotes(
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromEth2Dai(takerToken, makerToken, takerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromEth2Dai', callResults);
},
};
},
getCurveSellQuotes(
curveAddress: string,
fromTokenIdx: number,
toTokenIdx: number,
takerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleSellsFromCurve(
curveAddress,
new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx),
takerFillAmounts,
)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromCurve', callResults);
},
};
},
getUniswapBuyQuotes(
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleBuysFromUniswap(takerToken, makerToken, makerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromUniswap', callResults);
},
};
},
getEth2DaiBuyQuotes(
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
): BatchedOperation<BigNumber[]> {
return {
encodeCall: contract => {
return contract
.sampleBuysFromEth2Dai(takerToken, makerToken, makerFillAmounts)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromEth2Dai', callResults);
},
};
},
getMedianSellRate(
sources: ERC20BridgeSource[],
makerToken: string,
takerToken: string,
takerFillAmount: BigNumber,
liquidityProviderRegistryAddress?: string | undefined,
): BatchedOperation<BigNumber> {
const getSellQuotes = samplerOperations.getSellQuotes(
sources,
makerToken,
takerToken,
[takerFillAmount],
liquidityProviderRegistryAddress,
);
return {
encodeCall: contract => {
const subCalls = [getSellQuotes.encodeCall(contract)];
return contract.batchCall(subCalls).getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
const rawSubCallResults = contract.getABIDecodedReturnData<string[]>('batchCall', callResults);
const samples = await getSellQuotes.handleCallResultsAsync(contract, rawSubCallResults[0]);
if (samples.length === 0) {
return new BigNumber(0);
}
const flatSortedSamples = samples
.reduce((acc, v) => acc.concat(...v))
.sort((a, b) => a.output.comparedTo(b.output));
if (flatSortedSamples.length === 0) {
return new BigNumber(0);
}
const medianSample = flatSortedSamples[Math.floor(flatSortedSamples.length / 2)];
return medianSample.output.div(medianSample.input);
},
};
},
constant<T>(result: T): BatchedOperation<T> {
return {
encodeCall: contract => {
return '0x';
},
handleCallResultsAsync: async (contract, callResults) => {
return result;
},
};
},
getLiquidityProviderFromRegistry(
registryAddress: string,
takerToken: string,
makerToken: string,
): BatchedOperation<string> {
return {
encodeCall: contract => {
return contract
.getLiquidityProviderFromRegistry(registryAddress, takerToken, makerToken)
.getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
return contract.getABIDecodedReturnData<string>('getLiquidityProviderFromRegistry', callResults);
},
};
},
getSellQuotes(
sources: ERC20BridgeSource[],
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
liquidityProviderRegistryAddress?: string | undefined,
): BatchedOperation<DexSample[][]> {
const subOps = sources
.map(source => {
let batchedOperation;
if (source === ERC20BridgeSource.Eth2Dai) {
batchedOperation = samplerOperations.getEth2DaiSellQuotes(makerToken, takerToken, takerFillAmounts);
} else if (source === ERC20BridgeSource.Uniswap) {
batchedOperation = samplerOperations.getUniswapSellQuotes(makerToken, takerToken, takerFillAmounts);
} else if (source === ERC20BridgeSource.Kyber) {
batchedOperation = samplerOperations.getKyberSellQuotes(makerToken, takerToken, takerFillAmounts);
} else if (
source === ERC20BridgeSource.CurveUsdcDai ||
source === ERC20BridgeSource.CurveUsdcDaiUsdt ||
source === ERC20BridgeSource.CurveUsdcDaiUsdtTusd
) {
const { curveAddress, tokens } = constants.DEFAULT_CURVE_OPTS[source];
const fromTokenIdx = tokens.indexOf(takerToken);
const toTokenIdx = tokens.indexOf(makerToken);
if (fromTokenIdx !== -1 && toTokenIdx !== -1) {
batchedOperation = samplerOperations.getCurveSellQuotes(
curveAddress,
fromTokenIdx,
toTokenIdx,
takerFillAmounts,
);
}
} else if (source === ERC20BridgeSource.LiquidityProvider) {
if (liquidityProviderRegistryAddress === undefined) {
throw new Error(
'Cannot sample liquidity from a LiquidityProvider liquidity pool, if a registry is not provided.',
);
}
batchedOperation = samplerOperations.getLiquidityProviderSellQuotes(
liquidityProviderRegistryAddress,
takerToken,
makerToken,
takerFillAmounts,
);
} else {
throw new Error(`Unsupported sell sample source: ${source}`);
}
return { batchedOperation, source };
})
.filter(op => op.batchedOperation) as Array<{
batchedOperation: BatchedOperation<BigNumber[]>;
source: ERC20BridgeSource;
}>;
return {
encodeCall: contract => {
const subCalls = subOps.map(op => op.batchedOperation.encodeCall(contract));
return contract.batchCall(subCalls).getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
const rawSubCallResults = contract.getABIDecodedReturnData<string[]>('batchCall', callResults);
const samples = await Promise.all(
subOps.map(async (op, i) =>
op.batchedOperation.handleCallResultsAsync(contract, rawSubCallResults[i]),
),
);
return subOps.map((op, i) => {
return samples[i].map((output, j) => ({
source: op.source,
output,
input: takerFillAmounts[j],
}));
});
},
};
},
getBuyQuotes(
sources: ERC20BridgeSource[],
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
liquidityProviderRegistryAddress?: string | undefined,
): BatchedOperation<DexSample[][]> {
const subOps = sources.map(source => {
if (source === ERC20BridgeSource.Eth2Dai) {
return samplerOperations.getEth2DaiBuyQuotes(makerToken, takerToken, makerFillAmounts);
} else if (source === ERC20BridgeSource.Uniswap) {
return samplerOperations.getUniswapBuyQuotes(makerToken, takerToken, makerFillAmounts);
} else if (source === ERC20BridgeSource.LiquidityProvider) {
if (liquidityProviderRegistryAddress === undefined) {
throw new Error(
'Cannot sample liquidity from a LiquidityProvider liquidity pool, if a registry is not provided.',
);
}
return samplerOperations.getLiquidityProviderBuyQuotes(
liquidityProviderRegistryAddress,
takerToken,
makerToken,
makerFillAmounts,
);
} else {
throw new Error(`Unsupported buy sample source: ${source}`);
}
});
return {
encodeCall: contract => {
const subCalls = subOps.map(op => op.encodeCall(contract));
return contract.batchCall(subCalls).getABIEncodedTransactionData();
},
handleCallResultsAsync: async (contract, callResults) => {
const rawSubCallResults = contract.getABIDecodedReturnData<string[]>('batchCall', callResults);
const samples = await Promise.all(
subOps.map(async (op, i) => op.handleCallResultsAsync(contract, rawSubCallResults[i])),
);
return sources.map((source, i) => {
return samples[i].map((output, j) => ({
source,
output,
input: makerFillAmounts[j],
}));
});
},
};
},
};

View File

@ -393,7 +393,9 @@ describe('MarketOperationUtils tests', () => {
...DEFAULT_OPTS,
excludedSources: [],
});
expect(args.sources.sort()).to.deep.eq(SELL_SOURCES.concat([ERC20BridgeSource.LiquidityProvider]).sort());
expect(args.sources.sort()).to.deep.eq(
SELL_SOURCES.concat([ERC20BridgeSource.LiquidityProvider]).sort(),
);
expect(args.liquidityProviderAddress).to.eql(registryAddress);
});
@ -687,7 +689,9 @@ describe('MarketOperationUtils tests', () => {
...DEFAULT_OPTS,
excludedSources: [],
});
expect(args.sources.sort()).to.deep.eq(BUY_SOURCES.concat([ERC20BridgeSource.LiquidityProvider]).sort());
expect(args.sources.sort()).to.deep.eq(
BUY_SOURCES.concat([ERC20BridgeSource.LiquidityProvider]).sort(),
);
expect(args.liquidityProviderAddress).to.eql(registryAddress);
});

View File

@ -33,8 +33,6 @@ import { assert } from '@0x/assert';
import * as ethers from 'ethers';
// tslint:enable:no-unused-variable
/* istanbul ignore next */
// tslint:disable:array-type
// tslint:disable:no-parameter-reassignment
@ -43,14 +41,14 @@ export class DummyLiquidityProviderContract extends BaseContract {
/**
* @ignore
*/
public static deployedBytecode: string | undefined;
public static contractName = 'DummyLiquidityProvider';
public static deployedBytecode: string | undefined;
public static contractName = 'DummyLiquidityProvider';
private readonly _methodABIIndex: { [name: string]: number } = {};
public static async deployFrom0xArtifactAsync(
public static async deployFrom0xArtifactAsync(
artifact: ContractArtifact | SimpleContractArtifact,
supportedProvider: SupportedProvider,
txDefaults: Partial<TxData>,
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
): Promise<DummyLiquidityProviderContract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
@ -69,7 +67,13 @@ public static async deployFrom0xArtifactAsync(
logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi;
}
}
return DummyLiquidityProviderContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, );
return DummyLiquidityProviderContract.deployAsync(
bytecode,
abi,
provider,
txDefaults,
logDecodeDependenciesAbiOnly,
);
}
public static async deployWithLibrariesFrom0xArtifactAsync(
@ -77,7 +81,7 @@ public static async deployFrom0xArtifactAsync(
libraryArtifacts: { [libraryName: string]: ContractArtifact },
supportedProvider: SupportedProvider,
txDefaults: Partial<TxData>,
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
): Promise<DummyLiquidityProviderContract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
@ -99,13 +103,16 @@ public static async deployFrom0xArtifactAsync(
artifact,
libraryArtifacts,
new Web3Wrapper(provider),
txDefaults
txDefaults,
);
const bytecode = linkLibrariesInBytecode(
artifact,
libraryAddresses,
const bytecode = linkLibrariesInBytecode(artifact, libraryAddresses);
return DummyLiquidityProviderContract.deployAsync(
bytecode,
abi,
provider,
txDefaults,
logDecodeDependenciesAbiOnly,
);
return DummyLiquidityProviderContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, );
}
public static async deployAsync(
@ -123,11 +130,7 @@ public static async deployFrom0xArtifactAsync(
]);
const provider = providerUtils.standardizeOrThrow(supportedProvider);
const constructorAbi = BaseContract._lookupConstructorAbi(abi);
[] = BaseContract._formatABIDataItemList(
constructorAbi.inputs,
[],
BaseContract._bigNumberToString,
);
[] = BaseContract._formatABIDataItemList(constructorAbi.inputs, [], BaseContract._bigNumberToString);
const iface = new ethers.utils.Interface(abi);
const deployInfo = iface.deployFunction;
const txData = deployInfo.encode(bytecode, []);
@ -143,7 +146,12 @@ public static async deployFrom0xArtifactAsync(
logUtils.log(`transactionHash: ${txHash}`);
const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
logUtils.log(`DummyLiquidityProvider successfully deployed at ${txReceipt.contractAddress}`);
const contractInstance = new DummyLiquidityProviderContract(txReceipt.contractAddress as string, provider, txDefaults, logDecodeDependencies);
const contractInstance = new DummyLiquidityProviderContract(
txReceipt.contractAddress as string,
provider,
txDefaults,
logDecodeDependencies,
);
contractInstance.constructorArgs = [];
return contractInstance;
}
@ -153,16 +161,14 @@ public static async deployFrom0xArtifactAsync(
*/
public static ABI(): ContractAbi {
const abi = [
{
inputs: [
],
outputs: [
],
{
inputs: [],
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'constructor',
},
{
{
constant: true,
inputs: [
{
@ -189,7 +195,7 @@ public static async deployFrom0xArtifactAsync(
stateMutability: 'view',
type: 'function',
},
{
{
constant: true,
inputs: [
{
@ -246,10 +252,7 @@ public static async deployFrom0xArtifactAsync(
libraryAddresses,
);
// Deploy this library.
const linkedLibraryBytecode = linkLibrariesInBytecode(
libraryArtifact,
libraryAddresses,
);
const linkedLibraryBytecode = linkLibrariesInBytecode(libraryArtifact, libraryAddresses);
const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync(
{
data: linkedLibraryBytecode,
@ -300,88 +303,74 @@ public static async deployFrom0xArtifactAsync(
/**
* Quotes the amount of `takerToken` that would need to be sold in
* order to obtain `buyAmount` of `makerToken`.
* @param takerToken Address of the taker token (what to sell).
* @param makerToken Address of the maker token (what to buy).
* @param buyAmount Amount of `makerToken` to buy.
* @returns takerTokenAmount Amount of &#x60;takerToken&#x60; that would need to be sold.
* order to obtain `buyAmount` of `makerToken`.
* @param takerToken Address of the taker token (what to sell).
* @param makerToken Address of the maker token (what to buy).
* @param buyAmount Amount of `makerToken` to buy.
* @returns takerTokenAmount Amount of &#x60;takerToken&#x60; that would need to be sold.
*/
public getBuyQuote(
takerToken: string,
makerToken: string,
buyAmount: BigNumber,
): ContractFunctionObj<BigNumber
> {
const self = this as any as DummyLiquidityProviderContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isBigNumber('buyAmount', buyAmount);
public getBuyQuote(takerToken: string, makerToken: string, buyAmount: BigNumber): ContractFunctionObj<BigNumber> {
const self = (this as any) as DummyLiquidityProviderContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isBigNumber('buyAmount', buyAmount);
const functionSignature = 'getBuyQuote(address,address,uint256)';
return {
async callAsync(
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<BigNumber
> {
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
BaseContract._assertCallParams(callData, defaultBlock);
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
const rawCallResult = await self._performCallAsync(
{ ...callData, data: this.getABIEncodedTransactionData() },
defaultBlock,
);
const abiEncoder = self._lookupAbiEncoder(functionSignature);
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
return abiEncoder.strictDecodeReturnValue<BigNumber
>(rawCallResult);
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
},
getABIEncodedTransactionData(): string {
return self._strictEncodeArguments(functionSignature, [takerToken.toLowerCase(),
makerToken.toLowerCase(),
buyAmount
]);
return self._strictEncodeArguments(functionSignature, [
takerToken.toLowerCase(),
makerToken.toLowerCase(),
buyAmount,
]);
},
}
};
};
}
/**
* Quotes the amount of `makerToken` that would be obtained by
* selling `sellAmount` of `takerToken`.
* @param takerToken Address of the taker token (what to sell).
* @param makerToken Address of the maker token (what to buy).
* @param sellAmount Amount of `takerToken` to sell.
* @returns makerTokenAmount Amount of &#x60;makerToken&#x60; that would be obtained.
* selling `sellAmount` of `takerToken`.
* @param takerToken Address of the taker token (what to sell).
* @param makerToken Address of the maker token (what to buy).
* @param sellAmount Amount of `takerToken` to sell.
* @returns makerTokenAmount Amount of &#x60;makerToken&#x60; that would be obtained.
*/
public getSellQuote(
takerToken: string,
makerToken: string,
sellAmount: BigNumber,
): ContractFunctionObj<BigNumber
> {
const self = this as any as DummyLiquidityProviderContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isBigNumber('sellAmount', sellAmount);
public getSellQuote(takerToken: string, makerToken: string, sellAmount: BigNumber): ContractFunctionObj<BigNumber> {
const self = (this as any) as DummyLiquidityProviderContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isBigNumber('sellAmount', sellAmount);
const functionSignature = 'getSellQuote(address,address,uint256)';
return {
async callAsync(
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<BigNumber
> {
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
BaseContract._assertCallParams(callData, defaultBlock);
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
const rawCallResult = await self._performCallAsync(
{ ...callData, data: this.getABIEncodedTransactionData() },
defaultBlock,
);
const abiEncoder = self._lookupAbiEncoder(functionSignature);
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
return abiEncoder.strictDecodeReturnValue<BigNumber
>(rawCallResult);
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
},
getABIEncodedTransactionData(): string {
return self._strictEncodeArguments(functionSignature, [takerToken.toLowerCase(),
makerToken.toLowerCase(),
sellAmount
]);
return self._strictEncodeArguments(functionSignature, [
takerToken.toLowerCase(),
makerToken.toLowerCase(),
sellAmount,
]);
},
}
};
};
}
constructor(
address: string,
@ -390,9 +379,17 @@ public static async deployFrom0xArtifactAsync(
logDecodeDependencies?: { [contractName: string]: ContractAbi },
deployedBytecode: string | undefined = DummyLiquidityProviderContract.deployedBytecode,
) {
super('DummyLiquidityProvider', DummyLiquidityProviderContract.ABI(), address, supportedProvider, txDefaults, logDecodeDependencies, deployedBytecode);
super(
'DummyLiquidityProvider',
DummyLiquidityProviderContract.ABI(),
address,
supportedProvider,
txDefaults,
logDecodeDependencies,
deployedBytecode,
);
classUtils.bindAll(this, ['_abiEncoderByFunctionSignature', 'address', '_web3Wrapper']);
DummyLiquidityProviderContract.ABI().forEach((item, index) => {
DummyLiquidityProviderContract.ABI().forEach((item, index) => {
if (item.type === 'function') {
const methodAbi = item as MethodAbi;
this._methodABIIndex[methodAbi.name] = index;

View File

@ -33,8 +33,6 @@ import { assert } from '@0x/assert';
import * as ethers from 'ethers';
// tslint:enable:no-unused-variable
/* istanbul ignore next */
// tslint:disable:array-type
// tslint:disable:no-parameter-reassignment
@ -43,14 +41,14 @@ export class DummyLiquidityProviderRegistryContract extends BaseContract {
/**
* @ignore
*/
public static deployedBytecode: string | undefined;
public static contractName = 'DummyLiquidityProviderRegistry';
public static deployedBytecode: string | undefined;
public static contractName = 'DummyLiquidityProviderRegistry';
private readonly _methodABIIndex: { [name: string]: number } = {};
public static async deployFrom0xArtifactAsync(
public static async deployFrom0xArtifactAsync(
artifact: ContractArtifact | SimpleContractArtifact,
supportedProvider: SupportedProvider,
txDefaults: Partial<TxData>,
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
): Promise<DummyLiquidityProviderRegistryContract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
@ -69,7 +67,13 @@ public static async deployFrom0xArtifactAsync(
logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi;
}
}
return DummyLiquidityProviderRegistryContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, );
return DummyLiquidityProviderRegistryContract.deployAsync(
bytecode,
abi,
provider,
txDefaults,
logDecodeDependenciesAbiOnly,
);
}
public static async deployWithLibrariesFrom0xArtifactAsync(
@ -77,7 +81,7 @@ public static async deployFrom0xArtifactAsync(
libraryArtifacts: { [libraryName: string]: ContractArtifact },
supportedProvider: SupportedProvider,
txDefaults: Partial<TxData>,
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
): Promise<DummyLiquidityProviderRegistryContract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
@ -99,13 +103,16 @@ public static async deployFrom0xArtifactAsync(
artifact,
libraryArtifacts,
new Web3Wrapper(provider),
txDefaults
txDefaults,
);
const bytecode = linkLibrariesInBytecode(
artifact,
libraryAddresses,
const bytecode = linkLibrariesInBytecode(artifact, libraryAddresses);
return DummyLiquidityProviderRegistryContract.deployAsync(
bytecode,
abi,
provider,
txDefaults,
logDecodeDependenciesAbiOnly,
);
return DummyLiquidityProviderRegistryContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, );
}
public static async deployAsync(
@ -123,11 +130,7 @@ public static async deployFrom0xArtifactAsync(
]);
const provider = providerUtils.standardizeOrThrow(supportedProvider);
const constructorAbi = BaseContract._lookupConstructorAbi(abi);
[] = BaseContract._formatABIDataItemList(
constructorAbi.inputs,
[],
BaseContract._bigNumberToString,
);
[] = BaseContract._formatABIDataItemList(constructorAbi.inputs, [], BaseContract._bigNumberToString);
const iface = new ethers.utils.Interface(abi);
const deployInfo = iface.deployFunction;
const txData = deployInfo.encode(bytecode, []);
@ -143,7 +146,12 @@ public static async deployFrom0xArtifactAsync(
logUtils.log(`transactionHash: ${txHash}`);
const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
logUtils.log(`DummyLiquidityProviderRegistry successfully deployed at ${txReceipt.contractAddress}`);
const contractInstance = new DummyLiquidityProviderRegistryContract(txReceipt.contractAddress as string, provider, txDefaults, logDecodeDependencies);
const contractInstance = new DummyLiquidityProviderRegistryContract(
txReceipt.contractAddress as string,
provider,
txDefaults,
logDecodeDependencies,
);
contractInstance.constructorArgs = [];
return contractInstance;
}
@ -153,16 +161,14 @@ public static async deployFrom0xArtifactAsync(
*/
public static ABI(): ContractAbi {
const abi = [
{
inputs: [
],
outputs: [
],
{
inputs: [],
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'constructor',
},
{
{
constant: true,
inputs: [
{
@ -185,7 +191,7 @@ public static async deployFrom0xArtifactAsync(
stateMutability: 'view',
type: 'function',
},
{
{
constant: false,
inputs: [
{
@ -202,8 +208,7 @@ public static async deployFrom0xArtifactAsync(
},
],
name: 'setLiquidityProviderForMarket',
outputs: [
],
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
@ -238,10 +243,7 @@ public static async deployFrom0xArtifactAsync(
libraryAddresses,
);
// Deploy this library.
const linkedLibraryBytecode = linkLibrariesInBytecode(
libraryArtifact,
libraryAddresses,
);
const linkedLibraryBytecode = linkLibrariesInBytecode(libraryArtifact, libraryAddresses);
const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync(
{
data: linkedLibraryBytecode,
@ -292,56 +294,50 @@ public static async deployFrom0xArtifactAsync(
/**
* Returns the address of pool for a market given market (xAsset, yAsset), or reverts if pool does not exist.
* @param takerToken First asset managed by pool.
* @param makerToken Second asset managed by pool.
* @returns Address of pool.
* @param takerToken First asset managed by pool.
* @param makerToken Second asset managed by pool.
* @returns Address of pool.
*/
public getLiquidityProviderForMarket(
takerToken: string,
makerToken: string,
): ContractFunctionObj<string
> {
const self = this as any as DummyLiquidityProviderRegistryContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
public getLiquidityProviderForMarket(takerToken: string, makerToken: string): ContractFunctionObj<string> {
const self = (this as any) as DummyLiquidityProviderRegistryContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
const functionSignature = 'getLiquidityProviderForMarket(address,address)';
return {
async callAsync(
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<string
> {
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<string> {
BaseContract._assertCallParams(callData, defaultBlock);
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
const rawCallResult = await self._performCallAsync(
{ ...callData, data: this.getABIEncodedTransactionData() },
defaultBlock,
);
const abiEncoder = self._lookupAbiEncoder(functionSignature);
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
return abiEncoder.strictDecodeReturnValue<string
>(rawCallResult);
return abiEncoder.strictDecodeReturnValue<string>(rawCallResult);
},
getABIEncodedTransactionData(): string {
return self._strictEncodeArguments(functionSignature, [takerToken.toLowerCase(),
makerToken.toLowerCase()
]);
return self._strictEncodeArguments(functionSignature, [
takerToken.toLowerCase(),
makerToken.toLowerCase(),
]);
},
}
};
};
}
/**
* Sets address of pool for a market given market (xAsset, yAsset).
* @param takerToken First asset managed by pool.
* @param makerToken Second asset managed by pool.
* @param poolAddress Address of pool.
* @param takerToken First asset managed by pool.
* @param makerToken Second asset managed by pool.
* @param poolAddress Address of pool.
*/
public setLiquidityProviderForMarket(
takerToken: string,
makerToken: string,
poolAddress: string,
): ContractTxFunctionObj<void
> {
const self = this as any as DummyLiquidityProviderRegistryContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isString('poolAddress', poolAddress);
takerToken: string,
makerToken: string,
poolAddress: string,
): ContractTxFunctionObj<void> {
const self = (this as any) as DummyLiquidityProviderRegistryContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isString('poolAddress', poolAddress);
const functionSignature = 'setLiquidityProviderForMarket(address,address,address)';
return {
@ -364,36 +360,32 @@ public static async deployFrom0xArtifactAsync(
): PromiseWithTransactionHash<TransactionReceiptWithDecodedLogs> {
return self._promiseWithTransactionHash(this.sendTransactionAsync(txData, opts), opts);
},
async estimateGasAsync(
txData?: Partial<TxData> | undefined,
): Promise<number> {
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
{ ...txData, data: this.getABIEncodedTransactionData() }
);
async estimateGasAsync(txData?: Partial<TxData> | undefined): Promise<number> {
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync({
...txData,
data: this.getABIEncodedTransactionData(),
});
return self._web3Wrapper.estimateGasAsync(txDataWithDefaults);
},
async callAsync(
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<void
> {
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
BaseContract._assertCallParams(callData, defaultBlock);
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
const rawCallResult = await self._performCallAsync(
{ ...callData, data: this.getABIEncodedTransactionData() },
defaultBlock,
);
const abiEncoder = self._lookupAbiEncoder(functionSignature);
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
return abiEncoder.strictDecodeReturnValue<void
>(rawCallResult);
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
},
getABIEncodedTransactionData(): string {
return self._strictEncodeArguments(functionSignature, [takerToken.toLowerCase(),
makerToken.toLowerCase(),
poolAddress.toLowerCase()
]);
return self._strictEncodeArguments(functionSignature, [
takerToken.toLowerCase(),
makerToken.toLowerCase(),
poolAddress.toLowerCase(),
]);
},
}
};
};
}
constructor(
address: string,
@ -402,9 +394,17 @@ public static async deployFrom0xArtifactAsync(
logDecodeDependencies?: { [contractName: string]: ContractAbi },
deployedBytecode: string | undefined = DummyLiquidityProviderRegistryContract.deployedBytecode,
) {
super('DummyLiquidityProviderRegistry', DummyLiquidityProviderRegistryContract.ABI(), address, supportedProvider, txDefaults, logDecodeDependencies, deployedBytecode);
super(
'DummyLiquidityProviderRegistry',
DummyLiquidityProviderRegistryContract.ABI(),
address,
supportedProvider,
txDefaults,
logDecodeDependencies,
deployedBytecode,
);
classUtils.bindAll(this, ['_abiEncoderByFunctionSignature', 'address', '_web3Wrapper']);
DummyLiquidityProviderRegistryContract.ABI().forEach((item, index) => {
DummyLiquidityProviderRegistryContract.ABI().forEach((item, index) => {
if (item.type === 'function') {
const methodAbi = item as MethodAbi;
this._methodABIIndex[methodAbi.name] = index;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -33,8 +33,6 @@ import { assert } from '@0x/assert';
import * as ethers from 'ethers';
// tslint:enable:no-unused-variable
/* istanbul ignore next */
// tslint:disable:array-type
// tslint:disable:no-parameter-reassignment
@ -43,14 +41,14 @@ export class ILiquidityProviderContract extends BaseContract {
/**
* @ignore
*/
public static deployedBytecode: string | undefined;
public static contractName = 'ILiquidityProvider';
public static deployedBytecode: string | undefined;
public static contractName = 'ILiquidityProvider';
private readonly _methodABIIndex: { [name: string]: number } = {};
public static async deployFrom0xArtifactAsync(
public static async deployFrom0xArtifactAsync(
artifact: ContractArtifact | SimpleContractArtifact,
supportedProvider: SupportedProvider,
txDefaults: Partial<TxData>,
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
): Promise<ILiquidityProviderContract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
@ -69,7 +67,13 @@ public static async deployFrom0xArtifactAsync(
logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi;
}
}
return ILiquidityProviderContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, );
return ILiquidityProviderContract.deployAsync(
bytecode,
abi,
provider,
txDefaults,
logDecodeDependenciesAbiOnly,
);
}
public static async deployWithLibrariesFrom0xArtifactAsync(
@ -77,7 +81,7 @@ public static async deployFrom0xArtifactAsync(
libraryArtifacts: { [libraryName: string]: ContractArtifact },
supportedProvider: SupportedProvider,
txDefaults: Partial<TxData>,
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
): Promise<ILiquidityProviderContract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
@ -99,13 +103,16 @@ public static async deployFrom0xArtifactAsync(
artifact,
libraryArtifacts,
new Web3Wrapper(provider),
txDefaults
txDefaults,
);
const bytecode = linkLibrariesInBytecode(
artifact,
libraryAddresses,
const bytecode = linkLibrariesInBytecode(artifact, libraryAddresses);
return ILiquidityProviderContract.deployAsync(
bytecode,
abi,
provider,
txDefaults,
logDecodeDependenciesAbiOnly,
);
return ILiquidityProviderContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, );
}
public static async deployAsync(
@ -123,11 +130,7 @@ public static async deployFrom0xArtifactAsync(
]);
const provider = providerUtils.standardizeOrThrow(supportedProvider);
const constructorAbi = BaseContract._lookupConstructorAbi(abi);
[] = BaseContract._formatABIDataItemList(
constructorAbi.inputs,
[],
BaseContract._bigNumberToString,
);
[] = BaseContract._formatABIDataItemList(constructorAbi.inputs, [], BaseContract._bigNumberToString);
const iface = new ethers.utils.Interface(abi);
const deployInfo = iface.deployFunction;
const txData = deployInfo.encode(bytecode, []);
@ -143,7 +146,12 @@ public static async deployFrom0xArtifactAsync(
logUtils.log(`transactionHash: ${txHash}`);
const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
logUtils.log(`ILiquidityProvider successfully deployed at ${txReceipt.contractAddress}`);
const contractInstance = new ILiquidityProviderContract(txReceipt.contractAddress as string, provider, txDefaults, logDecodeDependencies);
const contractInstance = new ILiquidityProviderContract(
txReceipt.contractAddress as string,
provider,
txDefaults,
logDecodeDependencies,
);
contractInstance.constructorArgs = [];
return contractInstance;
}
@ -153,7 +161,7 @@ public static async deployFrom0xArtifactAsync(
*/
public static ABI(): ContractAbi {
const abi = [
{
{
constant: false,
inputs: [
{
@ -188,7 +196,7 @@ public static async deployFrom0xArtifactAsync(
stateMutability: 'nonpayable',
type: 'function',
},
{
{
constant: true,
inputs: [
{
@ -215,7 +223,7 @@ public static async deployFrom0xArtifactAsync(
stateMutability: 'view',
type: 'function',
},
{
{
constant: true,
inputs: [
{
@ -272,10 +280,7 @@ public static async deployFrom0xArtifactAsync(
libraryAddresses,
);
// Deploy this library.
const linkedLibraryBytecode = linkLibrariesInBytecode(
libraryArtifact,
libraryAddresses,
);
const linkedLibraryBytecode = linkLibrariesInBytecode(libraryArtifact, libraryAddresses);
const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync(
{
data: linkedLibraryBytecode,
@ -326,27 +331,26 @@ public static async deployFrom0xArtifactAsync(
/**
* Transfers `amount` of the ERC20 `tokenAddress` from `from` to `to`.
* @param tokenAddress The address of the ERC20 token to transfer.
* @param from Address to transfer asset from.
* @param to Address to transfer asset to.
* @param amount Amount of asset to transfer.
* @param bridgeData Arbitrary asset data needed by the bridge contract.
* @returns success The magic bytes &#x60;0xdc1600f3&#x60; if successful.
* @param tokenAddress The address of the ERC20 token to transfer.
* @param from Address to transfer asset from.
* @param to Address to transfer asset to.
* @param amount Amount of asset to transfer.
* @param bridgeData Arbitrary asset data needed by the bridge contract.
* @returns success The magic bytes &#x60;0xdc1600f3&#x60; if successful.
*/
public bridgeTransferFrom(
tokenAddress: string,
from: string,
to: string,
amount: BigNumber,
bridgeData: string,
): ContractTxFunctionObj<string
> {
const self = this as any as ILiquidityProviderContract;
assert.isString('tokenAddress', tokenAddress);
assert.isString('from', from);
assert.isString('to', to);
assert.isBigNumber('amount', amount);
assert.isString('bridgeData', bridgeData);
tokenAddress: string,
from: string,
to: string,
amount: BigNumber,
bridgeData: string,
): ContractTxFunctionObj<string> {
const self = (this as any) as ILiquidityProviderContract;
assert.isString('tokenAddress', tokenAddress);
assert.isString('from', from);
assert.isString('to', to);
assert.isBigNumber('amount', amount);
assert.isString('bridgeData', bridgeData);
const functionSignature = 'bridgeTransferFrom(address,address,address,uint256,bytes)';
return {
@ -369,120 +373,104 @@ public static async deployFrom0xArtifactAsync(
): PromiseWithTransactionHash<TransactionReceiptWithDecodedLogs> {
return self._promiseWithTransactionHash(this.sendTransactionAsync(txData, opts), opts);
},
async estimateGasAsync(
txData?: Partial<TxData> | undefined,
): Promise<number> {
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
{ ...txData, data: this.getABIEncodedTransactionData() }
);
async estimateGasAsync(txData?: Partial<TxData> | undefined): Promise<number> {
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync({
...txData,
data: this.getABIEncodedTransactionData(),
});
return self._web3Wrapper.estimateGasAsync(txDataWithDefaults);
},
async callAsync(
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<string
> {
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<string> {
BaseContract._assertCallParams(callData, defaultBlock);
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
const rawCallResult = await self._performCallAsync(
{ ...callData, data: this.getABIEncodedTransactionData() },
defaultBlock,
);
const abiEncoder = self._lookupAbiEncoder(functionSignature);
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
return abiEncoder.strictDecodeReturnValue<string
>(rawCallResult);
return abiEncoder.strictDecodeReturnValue<string>(rawCallResult);
},
getABIEncodedTransactionData(): string {
return self._strictEncodeArguments(functionSignature, [tokenAddress.toLowerCase(),
from.toLowerCase(),
to.toLowerCase(),
amount,
bridgeData
]);
return self._strictEncodeArguments(functionSignature, [
tokenAddress.toLowerCase(),
from.toLowerCase(),
to.toLowerCase(),
amount,
bridgeData,
]);
},
}
};
};
}
/**
* Quotes the amount of `takerToken` that would need to be sold in
* order to obtain `buyAmount` of `makerToken`.
* @param takerToken Address of the taker token (what to sell).
* @param makerToken Address of the maker token (what to buy).
* @param buyAmount Amount of `makerToken` to buy.
* @returns takerTokenAmount Amount of &#x60;takerToken&#x60; that would need to be sold.
* order to obtain `buyAmount` of `makerToken`.
* @param takerToken Address of the taker token (what to sell).
* @param makerToken Address of the maker token (what to buy).
* @param buyAmount Amount of `makerToken` to buy.
* @returns takerTokenAmount Amount of &#x60;takerToken&#x60; that would need to be sold.
*/
public getBuyQuote(
takerToken: string,
makerToken: string,
buyAmount: BigNumber,
): ContractFunctionObj<BigNumber
> {
const self = this as any as ILiquidityProviderContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isBigNumber('buyAmount', buyAmount);
public getBuyQuote(takerToken: string, makerToken: string, buyAmount: BigNumber): ContractFunctionObj<BigNumber> {
const self = (this as any) as ILiquidityProviderContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isBigNumber('buyAmount', buyAmount);
const functionSignature = 'getBuyQuote(address,address,uint256)';
return {
async callAsync(
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<BigNumber
> {
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
BaseContract._assertCallParams(callData, defaultBlock);
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
const rawCallResult = await self._performCallAsync(
{ ...callData, data: this.getABIEncodedTransactionData() },
defaultBlock,
);
const abiEncoder = self._lookupAbiEncoder(functionSignature);
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
return abiEncoder.strictDecodeReturnValue<BigNumber
>(rawCallResult);
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
},
getABIEncodedTransactionData(): string {
return self._strictEncodeArguments(functionSignature, [takerToken.toLowerCase(),
makerToken.toLowerCase(),
buyAmount
]);
return self._strictEncodeArguments(functionSignature, [
takerToken.toLowerCase(),
makerToken.toLowerCase(),
buyAmount,
]);
},
}
};
};
}
/**
* Quotes the amount of `makerToken` that would be obtained by
* selling `sellAmount` of `takerToken`.
* @param takerToken Address of the taker token (what to sell).
* @param makerToken Address of the maker token (what to buy).
* @param sellAmount Amount of `takerToken` to sell.
* @returns makerTokenAmount Amount of &#x60;makerToken&#x60; that would be obtained.
* selling `sellAmount` of `takerToken`.
* @param takerToken Address of the taker token (what to sell).
* @param makerToken Address of the maker token (what to buy).
* @param sellAmount Amount of `takerToken` to sell.
* @returns makerTokenAmount Amount of &#x60;makerToken&#x60; that would be obtained.
*/
public getSellQuote(
takerToken: string,
makerToken: string,
sellAmount: BigNumber,
): ContractFunctionObj<BigNumber
> {
const self = this as any as ILiquidityProviderContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isBigNumber('sellAmount', sellAmount);
public getSellQuote(takerToken: string, makerToken: string, sellAmount: BigNumber): ContractFunctionObj<BigNumber> {
const self = (this as any) as ILiquidityProviderContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
assert.isBigNumber('sellAmount', sellAmount);
const functionSignature = 'getSellQuote(address,address,uint256)';
return {
async callAsync(
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<BigNumber
> {
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
BaseContract._assertCallParams(callData, defaultBlock);
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
const rawCallResult = await self._performCallAsync(
{ ...callData, data: this.getABIEncodedTransactionData() },
defaultBlock,
);
const abiEncoder = self._lookupAbiEncoder(functionSignature);
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
return abiEncoder.strictDecodeReturnValue<BigNumber
>(rawCallResult);
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
},
getABIEncodedTransactionData(): string {
return self._strictEncodeArguments(functionSignature, [takerToken.toLowerCase(),
makerToken.toLowerCase(),
sellAmount
]);
return self._strictEncodeArguments(functionSignature, [
takerToken.toLowerCase(),
makerToken.toLowerCase(),
sellAmount,
]);
},
}
};
};
}
constructor(
address: string,
@ -491,9 +479,17 @@ public static async deployFrom0xArtifactAsync(
logDecodeDependencies?: { [contractName: string]: ContractAbi },
deployedBytecode: string | undefined = ILiquidityProviderContract.deployedBytecode,
) {
super('ILiquidityProvider', ILiquidityProviderContract.ABI(), address, supportedProvider, txDefaults, logDecodeDependencies, deployedBytecode);
super(
'ILiquidityProvider',
ILiquidityProviderContract.ABI(),
address,
supportedProvider,
txDefaults,
logDecodeDependencies,
deployedBytecode,
);
classUtils.bindAll(this, ['_abiEncoderByFunctionSignature', 'address', '_web3Wrapper']);
ILiquidityProviderContract.ABI().forEach((item, index) => {
ILiquidityProviderContract.ABI().forEach((item, index) => {
if (item.type === 'function') {
const methodAbi = item as MethodAbi;
this._methodABIIndex[methodAbi.name] = index;

View File

@ -33,8 +33,6 @@ import { assert } from '@0x/assert';
import * as ethers from 'ethers';
// tslint:enable:no-unused-variable
/* istanbul ignore next */
// tslint:disable:array-type
// tslint:disable:no-parameter-reassignment
@ -43,14 +41,14 @@ export class ILiquidityProviderRegistryContract extends BaseContract {
/**
* @ignore
*/
public static deployedBytecode: string | undefined;
public static contractName = 'ILiquidityProviderRegistry';
public static deployedBytecode: string | undefined;
public static contractName = 'ILiquidityProviderRegistry';
private readonly _methodABIIndex: { [name: string]: number } = {};
public static async deployFrom0xArtifactAsync(
public static async deployFrom0xArtifactAsync(
artifact: ContractArtifact | SimpleContractArtifact,
supportedProvider: SupportedProvider,
txDefaults: Partial<TxData>,
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
): Promise<ILiquidityProviderRegistryContract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
@ -69,7 +67,13 @@ public static async deployFrom0xArtifactAsync(
logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi;
}
}
return ILiquidityProviderRegistryContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, );
return ILiquidityProviderRegistryContract.deployAsync(
bytecode,
abi,
provider,
txDefaults,
logDecodeDependenciesAbiOnly,
);
}
public static async deployWithLibrariesFrom0xArtifactAsync(
@ -77,7 +81,7 @@ public static async deployFrom0xArtifactAsync(
libraryArtifacts: { [libraryName: string]: ContractArtifact },
supportedProvider: SupportedProvider,
txDefaults: Partial<TxData>,
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
): Promise<ILiquidityProviderRegistryContract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
@ -99,13 +103,16 @@ public static async deployFrom0xArtifactAsync(
artifact,
libraryArtifacts,
new Web3Wrapper(provider),
txDefaults
txDefaults,
);
const bytecode = linkLibrariesInBytecode(
artifact,
libraryAddresses,
const bytecode = linkLibrariesInBytecode(artifact, libraryAddresses);
return ILiquidityProviderRegistryContract.deployAsync(
bytecode,
abi,
provider,
txDefaults,
logDecodeDependenciesAbiOnly,
);
return ILiquidityProviderRegistryContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, );
}
public static async deployAsync(
@ -123,11 +130,7 @@ public static async deployFrom0xArtifactAsync(
]);
const provider = providerUtils.standardizeOrThrow(supportedProvider);
const constructorAbi = BaseContract._lookupConstructorAbi(abi);
[] = BaseContract._formatABIDataItemList(
constructorAbi.inputs,
[],
BaseContract._bigNumberToString,
);
[] = BaseContract._formatABIDataItemList(constructorAbi.inputs, [], BaseContract._bigNumberToString);
const iface = new ethers.utils.Interface(abi);
const deployInfo = iface.deployFunction;
const txData = deployInfo.encode(bytecode, []);
@ -143,7 +146,12 @@ public static async deployFrom0xArtifactAsync(
logUtils.log(`transactionHash: ${txHash}`);
const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
logUtils.log(`ILiquidityProviderRegistry successfully deployed at ${txReceipt.contractAddress}`);
const contractInstance = new ILiquidityProviderRegistryContract(txReceipt.contractAddress as string, provider, txDefaults, logDecodeDependencies);
const contractInstance = new ILiquidityProviderRegistryContract(
txReceipt.contractAddress as string,
provider,
txDefaults,
logDecodeDependencies,
);
contractInstance.constructorArgs = [];
return contractInstance;
}
@ -153,7 +161,7 @@ public static async deployFrom0xArtifactAsync(
*/
public static ABI(): ContractAbi {
const abi = [
{
{
constant: true,
inputs: [
{
@ -206,10 +214,7 @@ public static async deployFrom0xArtifactAsync(
libraryAddresses,
);
// Deploy this library.
const linkedLibraryBytecode = linkLibrariesInBytecode(
libraryArtifact,
libraryAddresses,
);
const linkedLibraryBytecode = linkLibrariesInBytecode(libraryArtifact, libraryAddresses);
const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync(
{
data: linkedLibraryBytecode,
@ -260,43 +265,36 @@ public static async deployFrom0xArtifactAsync(
/**
* Returns the address of a liquidity provider for the given market
* (takerToken, makerToken), reverting if the pool does not exist.
* @param takerToken Taker asset managed by liquidity provider.
* @param makerToken Maker asset managed by liquidity provider.
* @returns Address of the liquidity provider.
* (takerToken, makerToken), reverting if the pool does not exist.
* @param takerToken Taker asset managed by liquidity provider.
* @param makerToken Maker asset managed by liquidity provider.
* @returns Address of the liquidity provider.
*/
public getLiquidityProviderForMarket(
takerToken: string,
makerToken: string,
): ContractFunctionObj<string
> {
const self = this as any as ILiquidityProviderRegistryContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
public getLiquidityProviderForMarket(takerToken: string, makerToken: string): ContractFunctionObj<string> {
const self = (this as any) as ILiquidityProviderRegistryContract;
assert.isString('takerToken', takerToken);
assert.isString('makerToken', makerToken);
const functionSignature = 'getLiquidityProviderForMarket(address,address)';
return {
async callAsync(
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<string
> {
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<string> {
BaseContract._assertCallParams(callData, defaultBlock);
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
const rawCallResult = await self._performCallAsync(
{ ...callData, data: this.getABIEncodedTransactionData() },
defaultBlock,
);
const abiEncoder = self._lookupAbiEncoder(functionSignature);
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
return abiEncoder.strictDecodeReturnValue<string
>(rawCallResult);
return abiEncoder.strictDecodeReturnValue<string>(rawCallResult);
},
getABIEncodedTransactionData(): string {
return self._strictEncodeArguments(functionSignature, [takerToken.toLowerCase(),
makerToken.toLowerCase()
]);
return self._strictEncodeArguments(functionSignature, [
takerToken.toLowerCase(),
makerToken.toLowerCase(),
]);
},
}
};
};
}
constructor(
address: string,
@ -305,9 +303,17 @@ public static async deployFrom0xArtifactAsync(
logDecodeDependencies?: { [contractName: string]: ContractAbi },
deployedBytecode: string | undefined = ILiquidityProviderRegistryContract.deployedBytecode,
) {
super('ILiquidityProviderRegistry', ILiquidityProviderRegistryContract.ABI(), address, supportedProvider, txDefaults, logDecodeDependencies, deployedBytecode);
super(
'ILiquidityProviderRegistry',
ILiquidityProviderRegistryContract.ABI(),
address,
supportedProvider,
txDefaults,
logDecodeDependencies,
deployedBytecode,
);
classUtils.bindAll(this, ['_abiEncoderByFunctionSignature', 'address', '_web3Wrapper']);
ILiquidityProviderRegistryContract.ABI().forEach((item, index) => {
ILiquidityProviderRegistryContract.ABI().forEach((item, index) => {
if (item.type === 'function') {
const methodAbi = item as MethodAbi;
this._methodABIIndex[methodAbi.name] = index;

View File

@ -160,4 +160,4 @@ export {
ContractFunctionObj,
ContractTxFunctionObj,
SubscriptionErrors,
} from '@0x/base-contract';
} from '@0x/base-contract';