// tslint:disable:no-consecutive-blank-lines ordered-imports align trailing-comma enum-naming // tslint:disable:whitespace no-unbound-method no-trailing-whitespace // tslint:disable:no-unused-variable import { AwaitTransactionSuccessOpts, ContractFunctionObj, ContractTxFunctionObj, SendTransactionOpts, BaseContract, PromiseWithTransactionHash, methodAbiToFunctionSignature, linkLibrariesInBytecode, } from '@0x/base-contract'; import { schemas } from '@0x/json-schemas'; import { BlockParam, BlockParamLiteral, BlockRange, CallData, ContractAbi, ContractArtifact, DecodedLogArgs, MethodAbi, TransactionReceiptWithDecodedLogs, TxData, TxDataPayable, SupportedProvider, } from 'ethereum-types'; import { BigNumber, classUtils, hexUtils, logUtils, providerUtils } from '@0x/utils'; import { EventCallback, IndexedFilterValues, SimpleContractArtifact } from '@0x/types'; import { Web3Wrapper } from '@0x/web3-wrapper'; 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 // tslint:disable-next-line:class-name export class ERC20BridgeSamplerContract extends BaseContract { /** * @ignore */ public static deployedBytecode: string | undefined; public static contractName = 'ERC20BridgeSampler'; private readonly _methodABIIndex: { [name: string]: number } = {}; public static async deployFrom0xArtifactAsync( artifact: ContractArtifact | SimpleContractArtifact, supportedProvider: SupportedProvider, txDefaults: Partial, logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact }, ): Promise { assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ schemas.addressSchema, schemas.numberSchema, schemas.jsNumber, ]); if (artifact.compilerOutput === undefined) { throw new Error('Compiler output not found in the artifact file'); } const provider = providerUtils.standardizeOrThrow(supportedProvider); const bytecode = artifact.compilerOutput.evm.bytecode.object; const abi = artifact.compilerOutput.abi; const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {}; if (Object.keys(logDecodeDependencies) !== undefined) { for (const key of Object.keys(logDecodeDependencies)) { logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi; } } return ERC20BridgeSamplerContract.deployAsync( bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, ); } public static async deployWithLibrariesFrom0xArtifactAsync( artifact: ContractArtifact, libraryArtifacts: { [libraryName: string]: ContractArtifact }, supportedProvider: SupportedProvider, txDefaults: Partial, logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact }, ): Promise { assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ schemas.addressSchema, schemas.numberSchema, schemas.jsNumber, ]); if (artifact.compilerOutput === undefined) { throw new Error('Compiler output not found in the artifact file'); } const provider = providerUtils.standardizeOrThrow(supportedProvider); const abi = artifact.compilerOutput.abi; const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {}; if (Object.keys(logDecodeDependencies) !== undefined) { for (const key of Object.keys(logDecodeDependencies)) { logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi; } } const libraryAddresses = await ERC20BridgeSamplerContract._deployLibrariesAsync( artifact, libraryArtifacts, new Web3Wrapper(provider), txDefaults, ); const bytecode = linkLibrariesInBytecode(artifact, libraryAddresses); return ERC20BridgeSamplerContract.deployAsync( bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, ); } public static async deployAsync( bytecode: string, abi: ContractAbi, supportedProvider: SupportedProvider, txDefaults: Partial, logDecodeDependencies: { [contractName: string]: ContractAbi }, ): Promise { assert.isHexString('bytecode', bytecode); assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ schemas.addressSchema, schemas.numberSchema, schemas.jsNumber, ]); const provider = providerUtils.standardizeOrThrow(supportedProvider); const constructorAbi = BaseContract._lookupConstructorAbi(abi); [] = BaseContract._formatABIDataItemList(constructorAbi.inputs, [], BaseContract._bigNumberToString); const iface = new ethers.utils.Interface(abi); const deployInfo = iface.deployFunction; const txData = deployInfo.encode(bytecode, []); const web3Wrapper = new Web3Wrapper(provider); const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync( { data: txData, ...txDefaults, }, web3Wrapper.estimateGasAsync.bind(web3Wrapper), ); const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults); logUtils.log(`transactionHash: ${txHash}`); const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); logUtils.log(`ERC20BridgeSampler successfully deployed at ${txReceipt.contractAddress}`); const contractInstance = new ERC20BridgeSamplerContract( txReceipt.contractAddress as string, provider, txDefaults, logDecodeDependencies, ); contractInstance.constructorArgs = []; return contractInstance; } /** * @returns The contract ABI */ public static ABI(): ContractAbi { const abi = [ { constant: true, inputs: [ { name: 'callDatas', type: 'bytes[]', }, ], name: 'batchCall', outputs: [ { name: 'callResults', type: 'bytes[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'registryAddress', type: 'address', }, { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, ], name: 'getLiquidityProviderFromRegistry', outputs: [ { name: 'providerAddress', type: 'address', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'orders', type: 'tuple[]', components: [ { name: 'makerAddress', type: 'address', }, { name: 'takerAddress', type: 'address', }, { name: 'feeRecipientAddress', type: 'address', }, { name: 'senderAddress', type: 'address', }, { name: 'makerAssetAmount', type: 'uint256', }, { name: 'takerAssetAmount', type: 'uint256', }, { name: 'makerFee', type: 'uint256', }, { name: 'takerFee', type: 'uint256', }, { name: 'expirationTimeSeconds', type: 'uint256', }, { name: 'salt', type: 'uint256', }, { name: 'makerAssetData', type: 'bytes', }, { name: 'takerAssetData', type: 'bytes', }, { name: 'makerFeeAssetData', type: 'bytes', }, { name: 'takerFeeAssetData', type: 'bytes', }, ], }, { name: 'orderSignatures', type: 'bytes[]', }, { name: 'devUtilsAddress', type: 'address', }, ], name: 'getOrderFillableMakerAssetAmounts', outputs: [ { name: 'orderFillableMakerAssetAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'orders', type: 'tuple[]', components: [ { name: 'makerAddress', type: 'address', }, { name: 'takerAddress', type: 'address', }, { name: 'feeRecipientAddress', type: 'address', }, { name: 'senderAddress', type: 'address', }, { name: 'makerAssetAmount', type: 'uint256', }, { name: 'takerAssetAmount', type: 'uint256', }, { name: 'makerFee', type: 'uint256', }, { name: 'takerFee', type: 'uint256', }, { name: 'expirationTimeSeconds', type: 'uint256', }, { name: 'salt', type: 'uint256', }, { name: 'makerAssetData', type: 'bytes', }, { name: 'takerAssetData', type: 'bytes', }, { name: 'makerFeeAssetData', type: 'bytes', }, { name: 'takerFeeAssetData', type: 'bytes', }, ], }, { name: 'orderSignatures', type: 'bytes[]', }, { name: 'devUtilsAddress', type: 'address', }, ], name: 'getOrderFillableTakerAssetAmounts', outputs: [ { name: 'orderFillableTakerAssetAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'curveAddress', type: 'address', }, { name: 'fromTokenIdx', type: 'int128', }, { name: 'toTokenIdx', type: 'int128', }, { name: 'makerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleBuysFromCurve', outputs: [ { name: 'takerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'makerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleBuysFromEth2Dai', outputs: [ { name: 'takerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'makerTokenAmounts', type: 'uint256[]', }, { name: 'opts', type: 'tuple', components: [ { name: 'targetSlippageBps', type: 'uint256', }, { name: 'maxIterations', type: 'uint256', }, ], }, ], name: 'sampleBuysFromKyberNetwork', outputs: [ { name: 'takerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'registryAddress', type: 'address', }, { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'makerTokenAmounts', type: 'uint256[]', }, { name: 'opts', type: 'tuple', components: [ { name: 'targetSlippageBps', type: 'uint256', }, { name: 'maxIterations', type: 'uint256', }, ], }, ], name: 'sampleBuysFromLiquidityProviderRegistry', outputs: [ { name: 'takerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'makerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleBuysFromUniswap', outputs: [ { name: 'takerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'path', type: 'address[]', }, { name: 'makerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleBuysFromUniswapV2', outputs: [ { name: 'takerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'curveAddress', type: 'address', }, { name: 'fromTokenIdx', type: 'int128', }, { name: 'toTokenIdx', type: 'int128', }, { name: 'takerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleSellsFromCurve', outputs: [ { name: 'makerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'takerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleSellsFromEth2Dai', outputs: [ { name: 'makerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'intermediateToken', type: 'address', }, { name: 'takerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleSellsFromEth2DaiHop', outputs: [ { name: 'makerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'takerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleSellsFromKyberNetwork', outputs: [ { name: 'makerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'registryAddress', type: 'address', }, { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'takerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleSellsFromLiquidityProviderRegistry', outputs: [ { name: 'makerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'multibridge', type: 'address', }, { name: 'takerToken', type: 'address', }, { name: 'intermediateToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'takerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleSellsFromMultiBridge', outputs: [ { name: 'makerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'takerToken', type: 'address', }, { name: 'makerToken', type: 'address', }, { name: 'takerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleSellsFromUniswap', outputs: [ { name: 'makerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, { constant: true, inputs: [ { name: 'path', type: 'address[]', }, { name: 'takerTokenAmounts', type: 'uint256[]', }, ], name: 'sampleSellsFromUniswapV2', outputs: [ { name: 'makerTokenAmounts', type: 'uint256[]', }, ], payable: false, stateMutability: 'view', type: 'function', }, ] as ContractAbi; return abi; } protected static async _deployLibrariesAsync( artifact: ContractArtifact, libraryArtifacts: { [libraryName: string]: ContractArtifact }, web3Wrapper: Web3Wrapper, txDefaults: Partial, libraryAddresses: { [libraryName: string]: string } = {}, ): Promise<{ [libraryName: string]: string }> { const links = artifact.compilerOutput.evm.bytecode.linkReferences; // Go through all linked libraries, recursively deploying them if necessary. for (const link of Object.values(links)) { for (const libraryName of Object.keys(link)) { if (!libraryAddresses[libraryName]) { // Library not yet deployed. const libraryArtifact = libraryArtifacts[libraryName]; if (!libraryArtifact) { throw new Error(`Missing artifact for linked library "${libraryName}"`); } // Deploy any dependent libraries used by this library. await ERC20BridgeSamplerContract._deployLibrariesAsync( libraryArtifact, libraryArtifacts, web3Wrapper, txDefaults, libraryAddresses, ); // Deploy this library. const linkedLibraryBytecode = linkLibrariesInBytecode(libraryArtifact, libraryAddresses); const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync( { data: linkedLibraryBytecode, ...txDefaults, }, web3Wrapper.estimateGasAsync.bind(web3Wrapper), ); const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults); logUtils.log(`transactionHash: ${txHash}`); const { contractAddress } = await web3Wrapper.awaitTransactionSuccessAsync(txHash); logUtils.log(`${libraryArtifact.contractName} successfully deployed at ${contractAddress}`); libraryAddresses[libraryArtifact.contractName] = contractAddress as string; } } } return libraryAddresses; } public getFunctionSignature(methodName: string): string { const index = this._methodABIIndex[methodName]; const methodAbi = ERC20BridgeSamplerContract.ABI()[index] as MethodAbi; // tslint:disable-line:no-unnecessary-type-assertion const functionSignature = methodAbiToFunctionSignature(methodAbi); return functionSignature; } public getABIDecodedTransactionData(methodName: string, callData: string): T { const functionSignature = this.getFunctionSignature(methodName); const self = (this as any) as ERC20BridgeSamplerContract; const abiEncoder = self._lookupAbiEncoder(functionSignature); const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; } public getABIDecodedReturnData(methodName: string, callData: string): T { const functionSignature = this.getFunctionSignature(methodName); const self = (this as any) as ERC20BridgeSamplerContract; const abiEncoder = self._lookupAbiEncoder(functionSignature); const abiDecodedCallData = abiEncoder.strictDecodeReturnValue(callData); return abiDecodedCallData; } public getSelector(methodName: string): string { const functionSignature = this.getFunctionSignature(methodName); const self = (this as any) as ERC20BridgeSamplerContract; const abiEncoder = self._lookupAbiEncoder(functionSignature); return abiEncoder.getSelector(); } /** * Call multiple public functions on this contract in a single transaction. * @param callDatas ABI-encoded call data for each function call. * @returns callResults ABI-encoded results data for each call. */ public batchCall(callDatas: string[]): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isArray('callDatas', callDatas); const functionSignature = 'batchCall(bytes[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [callDatas]); }, }; } /** * Returns the address of a liquidity provider for the given market * (takerToken, makerToken), from a registry of liquidity providers. * Returns address(0) if no such provider exists in the registry. * @param takerToken Taker asset managed by liquidity provider. * @param makerToken Maker asset managed by liquidity provider. * @returns providerAddress Address of the liquidity provider. */ public getLiquidityProviderFromRegistry( registryAddress: string, takerToken: string, makerToken: string, ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('registryAddress', registryAddress); assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); const functionSignature = 'getLiquidityProviderFromRegistry(address,address,address)'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ registryAddress.toLowerCase(), takerToken.toLowerCase(), makerToken.toLowerCase(), ]); }, }; } /** * Queries the fillable taker asset amounts of native orders. * Effectively ignores orders that have empty signatures or * @param orders Native orders to query. * @param orderSignatures Signatures for each respective order in `orders`. * @param devUtilsAddress Address to the DevUtils contract. * @returns orderFillableMakerAssetAmounts How much maker asset can be filled by each order in `orders`. */ public getOrderFillableMakerAssetAmounts( orders: Array<{ makerAddress: string; takerAddress: string; feeRecipientAddress: string; senderAddress: string; makerAssetAmount: BigNumber; takerAssetAmount: BigNumber; makerFee: BigNumber; takerFee: BigNumber; expirationTimeSeconds: BigNumber; salt: BigNumber; makerAssetData: string; takerAssetData: string; makerFeeAssetData: string; takerFeeAssetData: string; }>, orderSignatures: string[], devUtilsAddress: string, ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isArray('orders', orders); assert.isArray('orderSignatures', orderSignatures); assert.isString('devUtilsAddress', devUtilsAddress); const functionSignature = 'getOrderFillableMakerAssetAmounts((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],bytes[],address)'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ orders, orderSignatures, devUtilsAddress.toLowerCase(), ]); }, }; } /** * Queries the fillable taker asset amounts of native orders. * Effectively ignores orders that have empty signatures or * maker/taker asset amounts (returning 0). * @param orders Native orders to query. * @param orderSignatures Signatures for each respective order in `orders`. * @param devUtilsAddress Address to the DevUtils contract. * @returns orderFillableTakerAssetAmounts How much taker asset can be filled by each order in `orders`. */ public getOrderFillableTakerAssetAmounts( orders: Array<{ makerAddress: string; takerAddress: string; feeRecipientAddress: string; senderAddress: string; makerAssetAmount: BigNumber; takerAssetAmount: BigNumber; makerFee: BigNumber; takerFee: BigNumber; expirationTimeSeconds: BigNumber; salt: BigNumber; makerAssetData: string; takerAssetData: string; makerFeeAssetData: string; takerFeeAssetData: string; }>, orderSignatures: string[], devUtilsAddress: string, ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isArray('orders', orders); assert.isArray('orderSignatures', orderSignatures); assert.isString('devUtilsAddress', devUtilsAddress); const functionSignature = 'getOrderFillableTakerAssetAmounts((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],bytes[],address)'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ orders, orderSignatures, devUtilsAddress.toLowerCase(), ]); }, }; } /** * Sample buy quotes from Curve. * @param curveAddress Address of the Curve contract. * @param fromTokenIdx Index of the taker token (what to sell). * @param toTokenIdx Index of the maker token (what to buy). * @param makerTokenAmounts Maker token buy amount for each sample. * @returns takerTokenAmounts Taker amounts sold at each maker token amount. */ public sampleBuysFromCurve( curveAddress: string, fromTokenIdx: BigNumber, toTokenIdx: BigNumber, makerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('curveAddress', curveAddress); assert.isBigNumber('fromTokenIdx', fromTokenIdx); assert.isBigNumber('toTokenIdx', toTokenIdx); assert.isArray('makerTokenAmounts', makerTokenAmounts); const functionSignature = 'sampleBuysFromCurve(address,int128,int128,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ curveAddress.toLowerCase(), fromTokenIdx, toTokenIdx, makerTokenAmounts, ]); }, }; } /** * Sample buy quotes from Eth2Dai/Oasis. * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @returns takerTokenAmounts Taker amounts sold at each maker token amount. */ public sampleBuysFromEth2Dai( takerToken: string, makerToken: string, makerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isArray('makerTokenAmounts', makerTokenAmounts); const functionSignature = 'sampleBuysFromEth2Dai(address,address,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ takerToken.toLowerCase(), makerToken.toLowerCase(), makerTokenAmounts, ]); }, }; } /** * Sample buy quotes from Kyber. * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @param makerTokenAmounts Maker token buy amount for each sample. * @param opts `FakeBuyOptions` specifying target slippage and max iterations. * @returns takerTokenAmounts Taker amounts sold at each maker token amount. */ public sampleBuysFromKyberNetwork( takerToken: string, makerToken: string, makerTokenAmounts: BigNumber[], opts: { targetSlippageBps: BigNumber; maxIterations: BigNumber }, ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isArray('makerTokenAmounts', makerTokenAmounts); const functionSignature = 'sampleBuysFromKyberNetwork(address,address,uint256[],(uint256,uint256))'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ takerToken.toLowerCase(), makerToken.toLowerCase(), makerTokenAmounts, opts, ]); }, }; } /** * Sample buy quotes from an arbitrary on-chain liquidity provider. * @param registryAddress Address of the liquidity provider registry contract. * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @param makerTokenAmounts Maker token buy amount for each sample. * @param opts `FakeBuyOptions` specifying target slippage and max iterations. * @returns takerTokenAmounts Taker amounts sold at each maker token amount. */ public sampleBuysFromLiquidityProviderRegistry( registryAddress: string, takerToken: string, makerToken: string, makerTokenAmounts: BigNumber[], opts: { targetSlippageBps: BigNumber; maxIterations: BigNumber }, ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('registryAddress', registryAddress); assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isArray('makerTokenAmounts', makerTokenAmounts); const functionSignature = 'sampleBuysFromLiquidityProviderRegistry(address,address,address,uint256[],(uint256,uint256))'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ registryAddress.toLowerCase(), takerToken.toLowerCase(), makerToken.toLowerCase(), makerTokenAmounts, opts, ]); }, }; } /** * Sample buy quotes from Uniswap. * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @param makerTokenAmounts Maker token sell amount for each sample. * @returns takerTokenAmounts Taker amounts sold at each maker token amount. */ public sampleBuysFromUniswap( takerToken: string, makerToken: string, makerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isArray('makerTokenAmounts', makerTokenAmounts); const functionSignature = 'sampleBuysFromUniswap(address,address,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ takerToken.toLowerCase(), makerToken.toLowerCase(), makerTokenAmounts, ]); }, }; } /** * Sample buy quotes from UniswapV2. * @param path Token route. Should be takerToken -> makerToken. * @param makerTokenAmounts Maker token buy amount for each sample. * @returns takerTokenAmounts Taker amounts sold at each maker token amount. */ public sampleBuysFromUniswapV2(path: string[], makerTokenAmounts: BigNumber[]): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isArray('path', path); assert.isArray('makerTokenAmounts', makerTokenAmounts); const functionSignature = 'sampleBuysFromUniswapV2(address[],uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [path, makerTokenAmounts]); }, }; } /** * Sample sell quotes from Curve. * @param curveAddress Address of the Curve contract. * @param fromTokenIdx Index of the taker token (what to sell). * @param toTokenIdx Index of the maker token (what to buy). * @param takerTokenAmounts Taker token sell amount for each sample. * @returns makerTokenAmounts Maker amounts bought at each taker token amount. */ public sampleSellsFromCurve( curveAddress: string, fromTokenIdx: BigNumber, toTokenIdx: BigNumber, takerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('curveAddress', curveAddress); assert.isBigNumber('fromTokenIdx', fromTokenIdx); assert.isBigNumber('toTokenIdx', toTokenIdx); assert.isArray('takerTokenAmounts', takerTokenAmounts); const functionSignature = 'sampleSellsFromCurve(address,int128,int128,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ curveAddress.toLowerCase(), fromTokenIdx, toTokenIdx, takerTokenAmounts, ]); }, }; } /** * Sample sell quotes from Eth2Dai/Oasis. * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @param takerTokenAmounts Taker token sell amount for each sample. * @returns makerTokenAmounts Maker amounts bought at each taker token amount. */ public sampleSellsFromEth2Dai( takerToken: string, makerToken: string, takerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isArray('takerTokenAmounts', takerTokenAmounts); const functionSignature = 'sampleSellsFromEth2Dai(address,address,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ takerToken.toLowerCase(), makerToken.toLowerCase(), takerTokenAmounts, ]); }, }; } /** * Sample sell quotes from Eth2Dai/Oasis using a hop to an intermediate token. * I.e WBTC/DAI via ETH or WBTC/ETH via DAI * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @param intermediateToken Address of the token to hop to. * @param takerTokenAmounts Taker token sell amount for each sample. * @returns makerTokenAmounts Maker amounts bought at each taker token amount. */ public sampleSellsFromEth2DaiHop( takerToken: string, makerToken: string, intermediateToken: string, takerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isString('intermediateToken', intermediateToken); assert.isArray('takerTokenAmounts', takerTokenAmounts); const functionSignature = 'sampleSellsFromEth2DaiHop(address,address,address,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ takerToken.toLowerCase(), makerToken.toLowerCase(), intermediateToken.toLowerCase(), takerTokenAmounts, ]); }, }; } /** * Sample sell quotes from Kyber. * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @param takerTokenAmounts Taker token sell amount for each sample. * @returns makerTokenAmounts Maker amounts bought at each taker token amount. */ public sampleSellsFromKyberNetwork( takerToken: string, makerToken: string, takerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isArray('takerTokenAmounts', takerTokenAmounts); const functionSignature = 'sampleSellsFromKyberNetwork(address,address,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ takerToken.toLowerCase(), makerToken.toLowerCase(), takerTokenAmounts, ]); }, }; } /** * Sample sell quotes from an arbitrary on-chain liquidity provider. * @param registryAddress Address of the liquidity provider registry contract. * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @param takerTokenAmounts Taker token sell amount for each sample. * @returns makerTokenAmounts Maker amounts bought at each taker token amount. */ public sampleSellsFromLiquidityProviderRegistry( registryAddress: string, takerToken: string, makerToken: string, takerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('registryAddress', registryAddress); assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isArray('takerTokenAmounts', takerTokenAmounts); const functionSignature = 'sampleSellsFromLiquidityProviderRegistry(address,address,address,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ registryAddress.toLowerCase(), takerToken.toLowerCase(), makerToken.toLowerCase(), takerTokenAmounts, ]); }, }; } /** * Sample sell quotes from MultiBridge. * @param multibridge Address of the MultiBridge contract. * @param takerToken Address of the taker token (what to sell). * @param intermediateToken The address of the intermediate token to use * in an indirect route. * @param makerToken Address of the maker token (what to buy). * @param takerTokenAmounts Taker token sell amount for each sample. * @returns makerTokenAmounts Maker amounts bought at each taker token amount. */ public sampleSellsFromMultiBridge( multibridge: string, takerToken: string, intermediateToken: string, makerToken: string, takerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('multibridge', multibridge); assert.isString('takerToken', takerToken); assert.isString('intermediateToken', intermediateToken); assert.isString('makerToken', makerToken); assert.isArray('takerTokenAmounts', takerTokenAmounts); const functionSignature = 'sampleSellsFromMultiBridge(address,address,address,address,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ multibridge.toLowerCase(), takerToken.toLowerCase(), intermediateToken.toLowerCase(), makerToken.toLowerCase(), takerTokenAmounts, ]); }, }; } /** * Sample sell quotes from Uniswap. * @param takerToken Address of the taker token (what to sell). * @param makerToken Address of the maker token (what to buy). * @param takerTokenAmounts Taker token sell amount for each sample. * @returns makerTokenAmounts Maker amounts bought at each taker token amount. */ public sampleSellsFromUniswap( takerToken: string, makerToken: string, takerTokenAmounts: BigNumber[], ): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isString('takerToken', takerToken); assert.isString('makerToken', makerToken); assert.isArray('takerTokenAmounts', takerTokenAmounts); const functionSignature = 'sampleSellsFromUniswap(address,address,uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [ takerToken.toLowerCase(), makerToken.toLowerCase(), takerTokenAmounts, ]); }, }; } /** * Sample sell quotes from UniswapV2. * @param path Token route. Should be takerToken -> makerToken * @param takerTokenAmounts Taker token sell amount for each sample. * @returns makerTokenAmounts Maker amounts bought at each taker token amount. */ public sampleSellsFromUniswapV2(path: string[], takerTokenAmounts: BigNumber[]): ContractFunctionObj { const self = (this as any) as ERC20BridgeSamplerContract; assert.isArray('path', path); assert.isArray('takerTokenAmounts', takerTokenAmounts); const functionSignature = 'sampleSellsFromUniswapV2(address[],uint256[])'; return { async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [path, takerTokenAmounts]); }, }; } constructor( address: string, supportedProvider: SupportedProvider, txDefaults?: Partial, logDecodeDependencies?: { [contractName: string]: ContractAbi }, deployedBytecode: string | undefined = ERC20BridgeSamplerContract.deployedBytecode, ) { super( 'ERC20BridgeSampler', ERC20BridgeSamplerContract.ABI(), address, supportedProvider, txDefaults, logDecodeDependencies, deployedBytecode, ); classUtils.bindAll(this, ['_abiEncoderByFunctionSignature', 'address', '_web3Wrapper']); ERC20BridgeSamplerContract.ABI().forEach((item, index) => { if (item.type === 'function') { const methodAbi = item as MethodAbi; this._methodABIIndex[methodAbi.name] = index; } }); } } // tslint:disable:max-file-line-count // tslint:enable:no-unbound-method no-parameter-reassignment no-consecutive-blank-lines ordered-imports align // tslint:enable:trailing-comma whitespace no-trailing-whitespace