// import { // blockchainTests, // constants, // expect, // getRandomInteger, // getRandomPortion, // randomAddress, // } from '@0x/contracts-test-utils'; // import { SignatureType } from '@0x/protocol-utils'; // import { BigNumber, hexUtils, NULL_BYTES } from '@0x/utils'; // import * as _ from 'lodash'; // // import { FillQuoteTransformerOrderType, LimitOrderFields } from '../../src'; // import { SamplerCallResult, SignedNativeOrder } from '../../src/types'; // import { artifacts } from '../artifacts'; // import { DummyLiquidityProviderContract, TestERC20BridgeSamplerContract } from '../wrappers'; // // // tslint:disable: custom-no-magic-numbers // // const { NULL_ADDRESS } = constants; // // HACK(dorothy-zbornak): Disabled because these tests are flakey and all this logic is moving to // // the sampler service anyway. // blockchainTests.skip('erc20-bridge-sampler', env => { // let testContract: TestERC20BridgeSamplerContract; // const RATE_DENOMINATOR = constants.ONE_ETHER; // const MIN_RATE = new BigNumber('0.01'); // const MAX_RATE = new BigNumber('100'); // const MIN_DECIMALS = 4; // const MAX_DECIMALS = 20; // const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; // const KYBER_SALT = '0x0ff3ca9d46195c39f9a12afb74207b4970349fb3cfb1e459bbf170298d326bc7'; // const UNISWAP_BASE_SALT = '0x1d6a6a0506b0b4a554b907a4c29d9f4674e461989d9c1921feb17b26716385ab'; // const UNISWAP_V2_SALT = '0xadc7fcb33c735913b8635927e66896b356a53a912ab2ceff929e60a04b53b3c1'; // const INVALID_TOKEN_PAIR_ERROR = 'ERC20BridgeSampler/INVALID_TOKEN_PAIR'; // const MAKER_TOKEN = randomAddress(); // const TAKER_TOKEN = randomAddress(); // const INTERMEDIATE_TOKEN = randomAddress(); // const KYBER_RESERVE_OFFSET = new BigNumber(0); // let KYBER_ADDRESS = ''; // let UNISWAP_ADDRESS = ''; // let UNISWAP_V2_ROUTER = ''; // // before(async () => { // testContract = await TestERC20BridgeSamplerContract.deployFrom0xArtifactAsync( // artifacts.TestERC20BridgeSampler, // env.provider, // { ...env.txDefaults, gas: 100e6 }, // {}, // ); // UNISWAP_V2_ROUTER = await testContract.uniswapV2Router().callAsync(); // KYBER_ADDRESS = await testContract.kyber().callAsync(); // UNISWAP_ADDRESS = await testContract.uniswap().callAsync(); // }); // // function getPackedHash(...args: string[]): string { // return hexUtils.hash(hexUtils.concat(...args.map(a => hexUtils.toHex(a)))); // } // // function getUniswapExchangeSalt(tokenAddress: string): string { // return getPackedHash(UNISWAP_BASE_SALT, tokenAddress); // } // // function getDeterministicRate(salt: string, sellToken: string, buyToken: string): BigNumber { // const hash = getPackedHash(salt, sellToken, buyToken); // const _minRate = RATE_DENOMINATOR.times(MIN_RATE); // const _maxRate = RATE_DENOMINATOR.times(MAX_RATE); // return new BigNumber(hash) // .mod(_maxRate.minus(_minRate)) // .plus(_minRate) // .div(RATE_DENOMINATOR); // } // // function getDeterministicTokenDecimals(token: string): number { // if (token === WETH_ADDRESS) { // return 18; // } // // HACK(dorothy-zbornak): Linter will complain about the addition not being // // between two numbers, even though they are. // // tslint:disable-next-line restrict-plus-operands // return new BigNumber(getPackedHash(token)).mod(MAX_DECIMALS - MIN_DECIMALS).toNumber() + MIN_DECIMALS; // } // // function getDeterministicSellQuote( // salt: string, // sellToken: string, // buyToken: string, // sellAmount: BigNumber, // ): BigNumber { // const sellBase = new BigNumber(10).pow(getDeterministicTokenDecimals(sellToken)); // const buyBase = new BigNumber(10).pow(getDeterministicTokenDecimals(buyToken)); // const rate = getDeterministicRate(salt, sellToken, buyToken); // return sellAmount // .times(rate) // .times(buyBase) // .dividedToIntegerBy(sellBase); // } // // function getDeterministicBuyQuote( // salt: string, // sellToken: string, // buyToken: string, // buyAmount: BigNumber, // ): BigNumber { // const sellBase = new BigNumber(10).pow(getDeterministicTokenDecimals(sellToken)); // const buyBase = new BigNumber(10).pow(getDeterministicTokenDecimals(buyToken)); // const rate = getDeterministicRate(salt, sellToken, buyToken); // return buyAmount // .times(sellBase) // .dividedToIntegerBy(rate) // .dividedToIntegerBy(buyBase); // } // // function areAddressesEqual(a: string, b: string): boolean { // return a.toLowerCase() === b.toLowerCase(); // } // // function getDeterministicUniswapSellQuote(sellToken: string, buyToken: string, sellAmount: BigNumber): BigNumber { // if (areAddressesEqual(buyToken, WETH_ADDRESS)) { // return getDeterministicSellQuote(getUniswapExchangeSalt(sellToken), sellToken, WETH_ADDRESS, sellAmount); // } // if (areAddressesEqual(sellToken, WETH_ADDRESS)) { // return getDeterministicSellQuote(getUniswapExchangeSalt(buyToken), buyToken, WETH_ADDRESS, sellAmount); // } // const ethBought = getDeterministicSellQuote( // getUniswapExchangeSalt(sellToken), // sellToken, // WETH_ADDRESS, // sellAmount, // ); // return getDeterministicSellQuote(getUniswapExchangeSalt(buyToken), buyToken, WETH_ADDRESS, ethBought); // } // // function getDeterministicUniswapBuyQuote(sellToken: string, buyToken: string, buyAmount: BigNumber): BigNumber { // if (areAddressesEqual(buyToken, WETH_ADDRESS)) { // return getDeterministicBuyQuote(getUniswapExchangeSalt(sellToken), WETH_ADDRESS, sellToken, buyAmount); // } // if (areAddressesEqual(sellToken, WETH_ADDRESS)) { // return getDeterministicBuyQuote(getUniswapExchangeSalt(buyToken), WETH_ADDRESS, buyToken, buyAmount); // } // const ethSold = getDeterministicBuyQuote(getUniswapExchangeSalt(buyToken), WETH_ADDRESS, buyToken, buyAmount); // return getDeterministicBuyQuote(getUniswapExchangeSalt(sellToken), WETH_ADDRESS, sellToken, ethSold); // } // // function getDeterministicSellQuotes( // sellToken: string, // buyToken: string, // sources: string[], // sampleAmounts: BigNumber[], // ): BigNumber[][] { // const quotes: BigNumber[][] = []; // for (const source of sources) { // const sampleOutputs = []; // for (const amount of sampleAmounts) { // if (source === 'Kyber') { // sampleOutputs.push(getDeterministicSellQuote(KYBER_SALT, sellToken, buyToken, amount)); // } else if (source === 'Uniswap') { // sampleOutputs.push(getDeterministicUniswapSellQuote(sellToken, buyToken, amount)); // } // } // quotes.push(sampleOutputs); // } // return quotes; // } // // function getDeterministicBuyQuotes( // sellToken: string, // buyToken: string, // sources: string[], // sampleAmounts: BigNumber[], // ): BigNumber[][] { // const quotes: BigNumber[][] = []; // for (const source of sources) { // const sampleOutputs = []; // for (const amount of sampleAmounts) { // if (source === 'Kyber') { // sampleOutputs.push(getDeterministicBuyQuote(KYBER_SALT, sellToken, buyToken, amount)); // } else if (source === 'Uniswap') { // sampleOutputs.push(getDeterministicUniswapBuyQuote(sellToken, buyToken, amount)); // } // } // quotes.push(sampleOutputs); // } // return quotes; // } // // function getDeterministicUniswapV2SellQuote(path: string[], sellAmount: BigNumber): BigNumber { // let bought = sellAmount; // for (let i = 0; i < path.length - 1; ++i) { // bought = getDeterministicSellQuote(UNISWAP_V2_SALT, path[i], path[i + 1], bought); // } // return bought; // } // // function getDeterministicUniswapV2BuyQuote(path: string[], buyAmount: BigNumber): BigNumber { // let sold = buyAmount; // for (let i = path.length - 1; i > 0; --i) { // sold = getDeterministicBuyQuote(UNISWAP_V2_SALT, path[i - 1], path[i], sold); // } // return sold; // } // // function getDeterministicFillableTakerAssetAmount(order: SignedNativeOrder): BigNumber { // const hash = getPackedHash(hexUtils.leftPad(order.order.salt)); // return new BigNumber(hash).mod(order.order.takerAmount); // } // // function getDeterministicFillableMakerAssetAmount(order: SignedNativeOrder): BigNumber { // const takerAmount = getDeterministicFillableTakerAssetAmount(order); // return order.order.makerAmount // .times(takerAmount) // .div(order.order.takerAmount) // .integerValue(BigNumber.ROUND_UP); // } // // function getSampleAmounts(tokenAddress: string, count?: number): BigNumber[] { // const tokenDecimals = getDeterministicTokenDecimals(tokenAddress); // const _upperLimit = getRandomPortion(getRandomInteger(1000, 50000).times(10 ** tokenDecimals)); // const _count = count || _.random(1, 16); // const d = _upperLimit.div(_count); // return _.times(_count, i => d.times((i + 1) / _count).integerValue()); // } // // function createOrder(makerToken: string, takerToken: string): SignedNativeOrder { // return { // order: { // chainId: 1337, // verifyingContract: randomAddress(), // maker: randomAddress(), // taker: randomAddress(), // pool: NULL_BYTES, // sender: NULL_ADDRESS, // feeRecipient: randomAddress(), // makerAmount: getRandomInteger(1, 1e18), // takerAmount: getRandomInteger(1, 1e18), // takerTokenFeeAmount: getRandomInteger(1, 1e18), // makerToken, // takerToken, // salt: new BigNumber(hexUtils.random()), // expiry: getRandomInteger(0, 2 ** 32), // }, // signature: { v: 1, r: NULL_BYTES, s: NULL_BYTES, signatureType: SignatureType.EthSign }, // type: FillQuoteTransformerOrderType.Limit, // }; // } // // function createOrders(makerToken: string, takerToken: string, count?: number): SignedNativeOrder[] { // return _.times(count || _.random(1, 16), () => createOrder(makerToken, takerToken)); // } // // async function enableFailTriggerAsync(): Promise { // await testContract.enableFailTrigger().awaitTransactionSuccessAsync({ value: 1 }); // } // // function expectQuotesWithinRange( // quotes: BigNumber[], // expectedQuotes: BigNumber[], // maxSlippage: BigNumber | number, // ): void { // quotes.forEach((_q, i) => { // // If we're within 1 base unit of a low decimal token // // then that's as good as we're going to get (and slippage is "high") // if ( // expectedQuotes[i].isZero() || // BigNumber.max(expectedQuotes[i], quotes[i]) // .minus(BigNumber.min(expectedQuotes[i], quotes[i])) // .eq(1) // ) { // return; // } // const slippage = quotes[i] // .dividedBy(expectedQuotes[i]) // .minus(1) // .decimalPlaces(4); // expect(slippage, `quote[${i}]: ${slippage} ${quotes[i]} ${expectedQuotes[i]}`).to.be.bignumber.gte(0); // expect(slippage, `quote[${i}] ${slippage} ${quotes[i]} ${expectedQuotes[i]}`).to.be.bignumber.lte( // new BigNumber(maxSlippage), // ); // }); // } // // describe('getOrderFillableTakerAssetAmounts()', () => { // it('returns the expected amount for each order', async () => { // const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN); // const expected = orders.map(getDeterministicFillableTakerAssetAmount); // const actual = await testContract // .getLimitOrderFillableTakerAssetAmounts( // // tslint:disable-next-line:no-unnecessary-type-assertion // orders.map(o => o.order as LimitOrderFields), // orders.map(o => o.signature), // NULL_ADDRESS, // ) // .callAsync(); // expect(actual).to.deep.eq(expected); // }); // // it('returns empty for no orders', async () => { // const actual = await testContract.getLimitOrderFillableTakerAssetAmounts([], [], NULL_ADDRESS).callAsync(); // expect(actual).to.deep.eq([]); // }); // }); // // describe('getOrderFillableMakerAssetAmounts()', () => { // it('returns the expected amount for each order', async () => { // const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN); // const expected = orders.map(getDeterministicFillableMakerAssetAmount); // const actual = await testContract // .getLimitOrderFillableMakerAssetAmounts( // // tslint:disable-next-line:no-unnecessary-type-assertion // orders.map(o => o.order as LimitOrderFields), // orders.map(o => o.signature), // NULL_ADDRESS, // ) // .callAsync(); // expect(actual).to.deep.eq(expected); // }); // // it('returns empty for no orders', async () => { // const actual = await testContract.getLimitOrderFillableMakerAssetAmounts([], [], NULL_ADDRESS).callAsync(); // expect(actual).to.deep.eq([]); // }); // }); // // blockchainTests.resets('sampleSellsFromKyberNetwork()', () => { // let kyberOpts = { // hintHandler: NULL_ADDRESS, // networkProxy: NULL_ADDRESS, // weth: WETH_ADDRESS, // reserveOffset: KYBER_RESERVE_OFFSET, // hint: NULL_BYTES, // }; // before(async () => { // await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync(); // kyberOpts = { // ...kyberOpts, // hintHandler: KYBER_ADDRESS, // networkProxy: KYBER_ADDRESS, // }; // }); // // it('throws if tokens are the same', async () => { // const tx = testContract.sampleSellsFromKyberNetwork(kyberOpts, MAKER_TOKEN, MAKER_TOKEN, []).callAsync(); // return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR); // }); // // it('can return no quotes', async () => { // const [, , quotes] = await testContract // .sampleSellsFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, []) // .callAsync(); // expect(quotes).to.deep.eq([]); // }); // // it('returns zero if token -> token fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const [, , quotes] = await testContract // .sampleSellsFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote token -> ETH', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicSellQuotes(TAKER_TOKEN, WETH_ADDRESS, ['Kyber'], sampleAmounts); // const [, , quotes] = await testContract // .sampleSellsFromKyberNetwork(kyberOpts, TAKER_TOKEN, WETH_ADDRESS, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote token -> token', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicSellQuotes(TAKER_TOKEN, MAKER_TOKEN, ['Kyber'], sampleAmounts); // const [, , quotes] = await testContract // .sampleSellsFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if token -> ETH fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const [, , quotes] = await testContract // .sampleSellsFromKyberNetwork(kyberOpts, TAKER_TOKEN, WETH_ADDRESS, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote ETH -> token', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicSellQuotes(WETH_ADDRESS, TAKER_TOKEN, ['Kyber'], sampleAmounts); // const [, , quotes] = await testContract // .sampleSellsFromKyberNetwork(kyberOpts, WETH_ADDRESS, TAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if ETH -> token fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const [, , quotes] = await testContract // .sampleSellsFromKyberNetwork(kyberOpts, WETH_ADDRESS, TAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // }); // // blockchainTests.resets('sampleBuysFromKyberNetwork()', () => { // let kyberOpts = { // hintHandler: NULL_ADDRESS, // networkProxy: NULL_ADDRESS, // weth: WETH_ADDRESS, // reserveOffset: KYBER_RESERVE_OFFSET, // hint: NULL_BYTES, // }; // const ACCEPTABLE_SLIPPAGE = 0.0005; // before(async () => { // await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync(); // kyberOpts = { // ...kyberOpts, // hintHandler: KYBER_ADDRESS, // networkProxy: KYBER_ADDRESS, // }; // }); // // it('throws if tokens are the same', async () => { // const tx = testContract.sampleBuysFromKyberNetwork(kyberOpts, MAKER_TOKEN, MAKER_TOKEN, []).callAsync(); // return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR); // }); // // it('can return no quotes', async () => { // const [, , quotes] = await testContract // .sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, []) // .callAsync(); // expect(quotes).to.deep.eq([]); // }); // // it('can quote token -> token', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicBuyQuotes(TAKER_TOKEN, MAKER_TOKEN, ['Kyber'], sampleAmounts); // const [, , quotes] = await testContract // .sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expectQuotesWithinRange(quotes, expectedQuotes, ACCEPTABLE_SLIPPAGE); // }); // // it('returns zero if token -> token fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const [, , quotes] = await testContract // .sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote token -> ETH', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicBuyQuotes(TAKER_TOKEN, WETH_ADDRESS, ['Kyber'], sampleAmounts); // const [, , quotes] = await testContract // .sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, WETH_ADDRESS, sampleAmounts) // .callAsync(); // expectQuotesWithinRange(quotes, expectedQuotes, ACCEPTABLE_SLIPPAGE); // }); // // it('returns zero if token -> ETH fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const [, , quotes] = await testContract // .sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, WETH_ADDRESS, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote ETH -> token', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicBuyQuotes(WETH_ADDRESS, TAKER_TOKEN, ['Kyber'], sampleAmounts); // const [, , quotes] = await testContract // .sampleBuysFromKyberNetwork(kyberOpts, WETH_ADDRESS, TAKER_TOKEN, sampleAmounts) // .callAsync(); // expectQuotesWithinRange(quotes, expectedQuotes, ACCEPTABLE_SLIPPAGE); // }); // // it('returns zero if ETH -> token fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const [, , quotes] = await testContract // .sampleBuysFromKyberNetwork(kyberOpts, WETH_ADDRESS, TAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // }); // // blockchainTests.resets('sampleSellsFromUniswap()', () => { // const UNISWAP_ETH_ADDRESS = NULL_ADDRESS; // before(async () => { // await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync(); // }); // // it('throws if tokens are the same', async () => { // const tx = testContract.sampleSellsFromUniswap(UNISWAP_ADDRESS, MAKER_TOKEN, MAKER_TOKEN, []).callAsync(); // return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR); // }); // // it('can return no quotes', async () => { // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, []) // .callAsync(); // expect(quotes).to.deep.eq([]); // }); // // it('can quote token -> token', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicSellQuotes(TAKER_TOKEN, MAKER_TOKEN, ['Uniswap'], sampleAmounts); // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if token -> token fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote token -> ETH', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicSellQuotes(TAKER_TOKEN, WETH_ADDRESS, ['Uniswap'], sampleAmounts); // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if token -> ETH fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote ETH -> token', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const [expectedQuotes] = getDeterministicSellQuotes(WETH_ADDRESS, TAKER_TOKEN, ['Uniswap'], sampleAmounts); // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if ETH -> token fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if no exchange exists for the maker token', async () => { // const nonExistantToken = randomAddress(); // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, nonExistantToken, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if no exchange exists for the taker token', async () => { // const nonExistantToken = randomAddress(); // const sampleAmounts = getSampleAmounts(nonExistantToken); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // const quotes = await testContract // .sampleSellsFromUniswap(UNISWAP_ADDRESS, nonExistantToken, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // }); // // blockchainTests.resets('sampleBuysFromUniswap()', () => { // const UNISWAP_ETH_ADDRESS = NULL_ADDRESS; // before(async () => { // await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync(); // }); // // it('throws if tokens are the same', async () => { // const tx = testContract.sampleBuysFromUniswap(UNISWAP_ADDRESS, MAKER_TOKEN, MAKER_TOKEN, []).callAsync(); // return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR); // }); // // it('can return no quotes', async () => { // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, []) // .callAsync(); // expect(quotes).to.deep.eq([]); // }); // // it('can quote token -> token', async () => { // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const [expectedQuotes] = getDeterministicBuyQuotes(TAKER_TOKEN, MAKER_TOKEN, ['Uniswap'], sampleAmounts); // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if token -> token fails', async () => { // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote token -> ETH', async () => { // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const [expectedQuotes] = getDeterministicBuyQuotes(TAKER_TOKEN, WETH_ADDRESS, ['Uniswap'], sampleAmounts); // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if token -> ETH fails', async () => { // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote ETH -> token', async () => { // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const [expectedQuotes] = getDeterministicBuyQuotes(WETH_ADDRESS, TAKER_TOKEN, ['Uniswap'], sampleAmounts); // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if ETH -> token fails', async () => { // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if no exchange exists for the maker token', async () => { // const nonExistantToken = randomAddress(); // const sampleAmounts = getSampleAmounts(nonExistantToken); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, nonExistantToken, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if no exchange exists for the taker token', async () => { // const nonExistantToken = randomAddress(); // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // const quotes = await testContract // .sampleBuysFromUniswap(UNISWAP_ADDRESS, nonExistantToken, MAKER_TOKEN, sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // }); // // describe('liquidity provider', () => { // const xAsset = randomAddress(); // const yAsset = randomAddress(); // const sampleAmounts = getSampleAmounts(yAsset); // let liquidityProvider: DummyLiquidityProviderContract; // // before(async () => { // liquidityProvider = await DummyLiquidityProviderContract.deployFrom0xArtifactAsync( // artifacts.DummyLiquidityProvider, // env.provider, // env.txDefaults, // {}, // ); // }); // // it('should be able to query sells from the liquidity provider', async () => { // const quotes = await testContract // .sampleSellsFromLiquidityProvider(liquidityProvider.address, yAsset, xAsset, sampleAmounts) // .callAsync(); // quotes.forEach((value, idx) => { // expect(value).is.bignumber.eql(sampleAmounts[idx].minus(1)); // }); // }); // // it('should be able to query buys from the liquidity provider', async () => { // const quotes = await testContract // .sampleBuysFromLiquidityProvider(liquidityProvider.address, yAsset, xAsset, sampleAmounts) // .callAsync(); // quotes.forEach((value, idx) => { // expect(value).is.bignumber.eql(sampleAmounts[idx].plus(1)); // }); // }); // // it('should just return zeros if the liquidity provider does not exist', async () => { // const quotes = await testContract // .sampleBuysFromLiquidityProvider(randomAddress(), yAsset, xAsset, sampleAmounts) // .callAsync(); // quotes.forEach(value => { // expect(value).is.bignumber.eql(constants.ZERO_AMOUNT); // }); // }); // }); // // blockchainTests.resets('sampleSellsFromUniswapV2()', () => { // function predictSellQuotes(path: string[], sellAmounts: BigNumber[]): BigNumber[] { // return sellAmounts.map(a => getDeterministicUniswapV2SellQuote(path, a)); // } // // it('can return no quotes', async () => { // const quotes = await testContract // .sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], []) // .callAsync(); // expect(quotes).to.deep.eq([]); // }); // // it('can quote token -> token', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = predictSellQuotes([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts); // const quotes = await testContract // .sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if token -> token fails', async () => { // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const quotes = await testContract // .sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote token -> token -> token', async () => { // const intermediateToken = randomAddress(); // const sampleAmounts = getSampleAmounts(TAKER_TOKEN); // const expectedQuotes = predictSellQuotes([TAKER_TOKEN, intermediateToken, MAKER_TOKEN], sampleAmounts); // const quotes = await testContract // .sampleSellsFromUniswapV2( // UNISWAP_V2_ROUTER, // [TAKER_TOKEN, intermediateToken, MAKER_TOKEN], // sampleAmounts, // ) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // }); // // blockchainTests.resets('sampleBuysFromUniswapV2()', () => { // function predictBuyQuotes(path: string[], buyAmounts: BigNumber[]): BigNumber[] { // return buyAmounts.map(a => getDeterministicUniswapV2BuyQuote(path, a)); // } // // it('can return no quotes', async () => { // const quotes = await testContract // .sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], []) // .callAsync(); // expect(quotes).to.deep.eq([]); // }); // // it('can quote token -> token', async () => { // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const expectedQuotes = predictBuyQuotes([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts); // const quotes = await testContract // .sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('returns zero if token -> token fails', async () => { // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT); // await enableFailTriggerAsync(); // const quotes = await testContract // .sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // // it('can quote token -> token -> token', async () => { // const intermediateToken = randomAddress(); // const sampleAmounts = getSampleAmounts(MAKER_TOKEN); // const expectedQuotes = predictBuyQuotes([TAKER_TOKEN, intermediateToken, MAKER_TOKEN], sampleAmounts); // const quotes = await testContract // .sampleBuysFromUniswapV2( // UNISWAP_V2_ROUTER, // [TAKER_TOKEN, intermediateToken, MAKER_TOKEN], // sampleAmounts, // ) // .callAsync(); // expect(quotes).to.deep.eq(expectedQuotes); // }); // }); // // describe('batchCall()', () => { // it('can call one function', async () => { // const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN); // const expected = orders.map(getDeterministicFillableTakerAssetAmount); // const calls = [ // testContract // .getLimitOrderFillableTakerAssetAmounts( // // tslint:disable-next-line:no-unnecessary-type-assertion // orders.map(o => o.order as LimitOrderFields), // orders.map(o => o.signature), // NULL_ADDRESS, // ) // .getABIEncodedTransactionData(), // ]; // const r = await testContract.batchCall(calls).callAsync(); // expect(r).to.be.length(1); // const actual = testContract.getABIDecodedReturnData( // 'getLimitOrderFillableTakerAssetAmounts', // r[0].data, // ); // expect(actual).to.deep.eq(expected); // }); // // it('can call two functions', async () => { // const numOrders = _.random(1, 10); // const orders = _.times(2, () => createOrders(MAKER_TOKEN, TAKER_TOKEN, numOrders)); // const expecteds = [ // orders[0].map(getDeterministicFillableTakerAssetAmount), // orders[1].map(getDeterministicFillableMakerAssetAmount), // ]; // const calls = [ // testContract // .getLimitOrderFillableTakerAssetAmounts( // // tslint:disable-next-line:no-unnecessary-type-assertion // orders[0].map(o => o.order as LimitOrderFields), // orders[0].map(o => o.signature), // NULL_ADDRESS, // ) // .getABIEncodedTransactionData(), // testContract // .getLimitOrderFillableMakerAssetAmounts( // // tslint:disable-next-line:no-unnecessary-type-assertion // orders[1].map(o => o.order as LimitOrderFields), // orders[1].map(o => o.signature), // NULL_ADDRESS, // ) // .getABIEncodedTransactionData(), // ]; // const r = await testContract.batchCall(calls).callAsync(); // expect(r).to.be.length(2); // expect( // testContract.getABIDecodedReturnData('getLimitOrderFillableTakerAssetAmounts', r[0].data), // ).to.deep.eq(expecteds[0]); // expect( // testContract.getABIDecodedReturnData('getLimitOrderFillableMakerAssetAmounts', r[1].data), // ).to.deep.eq(expecteds[1]); // }); // // it('can make recursive calls', async () => { // const numOrders = _.random(1, 10); // const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN, numOrders); // const expected = orders.map(getDeterministicFillableTakerAssetAmount); // let r = await testContract // .batchCall([ // testContract // .batchCall([ // testContract // .getLimitOrderFillableTakerAssetAmounts( // // tslint:disable-next-line:no-unnecessary-type-assertion // orders.map(o => o.order as LimitOrderFields), // orders.map(o => o.signature), // NULL_ADDRESS, // ) // .getABIEncodedTransactionData(), // ]) // .getABIEncodedTransactionData(), // ]) // .callAsync(); // expect(r).to.be.length(1); // r = testContract.getABIDecodedReturnData('batchCall', r[0].data); // expect(r).to.be.length(1); // expect( // testContract.getABIDecodedReturnData('getLimitOrderFillableTakerAssetAmounts', r[0].data), // ).to.deep.eq(expected); // }); // }); // // blockchainTests.resets('TwoHopSampler', () => { // before(async () => { // await testContract // .createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN, INTERMEDIATE_TOKEN]) // .awaitTransactionSuccessAsync(); // }); // // it('sampleTwoHopSell', async () => { // // tslint:disable-next-line no-unnecessary-type-assertion // const sellAmount = _.last(getSampleAmounts(TAKER_TOKEN))!; // const uniswapV2FirstHopPath = [TAKER_TOKEN, INTERMEDIATE_TOKEN]; // const uniswapV2FirstHop = testContract // .sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2FirstHopPath, [constants.ZERO_AMOUNT]) // .getABIEncodedTransactionData(); // // const uniswapV2SecondHopPath = [INTERMEDIATE_TOKEN, randomAddress(), MAKER_TOKEN]; // const uniswapV2SecondHop = testContract // .sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2SecondHopPath, [constants.ZERO_AMOUNT]) // .getABIEncodedTransactionData(); // // const firstHopQuotes = [getDeterministicUniswapV2SellQuote(uniswapV2FirstHopPath, sellAmount)]; // const expectedIntermediateAssetAmount = BigNumber.max(...firstHopQuotes); // const secondHopQuotes = [ // getDeterministicUniswapV2SellQuote(uniswapV2SecondHopPath, expectedIntermediateAssetAmount), // ]; // const expectedBuyAmount = BigNumber.max(...secondHopQuotes); // // const [firstHop, secondHop, buyAmount] = await testContract // .sampleTwoHopSell([uniswapV2FirstHop], [uniswapV2SecondHop], sellAmount) // .callAsync(); // expect(firstHop.sourceIndex, 'First hop source index').to.bignumber.equal( // firstHopQuotes.findIndex(quote => quote.isEqualTo(expectedIntermediateAssetAmount)), // ); // expect(secondHop.sourceIndex, 'Second hop source index').to.bignumber.equal( // secondHopQuotes.findIndex(quote => quote.isEqualTo(expectedBuyAmount)), // ); // expect(buyAmount, 'Two hop buy amount').to.bignumber.equal(expectedBuyAmount); // }); // it('sampleTwoHopBuy', async () => { // // tslint:disable-next-line no-unnecessary-type-assertion // const buyAmount = _.last(getSampleAmounts(MAKER_TOKEN))!; // const uniswapV2FirstHopPath = [TAKER_TOKEN, INTERMEDIATE_TOKEN]; // const uniswapV2FirstHop = testContract // .sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2FirstHopPath, [constants.ZERO_AMOUNT]) // .getABIEncodedTransactionData(); // // const uniswapV2SecondHopPath = [INTERMEDIATE_TOKEN, randomAddress(), MAKER_TOKEN]; // const uniswapV2SecondHop = testContract // .sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2SecondHopPath, [constants.ZERO_AMOUNT]) // .getABIEncodedTransactionData(); // // const secondHopQuotes = [getDeterministicUniswapV2BuyQuote(uniswapV2SecondHopPath, buyAmount)]; // const expectedIntermediateAssetAmount = BigNumber.min(...secondHopQuotes); // // const firstHopQuotes = [ // getDeterministicUniswapV2BuyQuote(uniswapV2FirstHopPath, expectedIntermediateAssetAmount), // ]; // const expectedSellAmount = BigNumber.min(...firstHopQuotes); // // const [firstHop, secondHop, sellAmount] = await testContract // .sampleTwoHopBuy([uniswapV2FirstHop], [uniswapV2SecondHop], buyAmount) // .callAsync(); // expect(firstHop.sourceIndex, 'First hop source index').to.bignumber.equal( // firstHopQuotes.findIndex(quote => quote.isEqualTo(expectedSellAmount)), // ); // expect(secondHop.sourceIndex, 'Second hop source index').to.bignumber.equal( // secondHopQuotes.findIndex(quote => quote.isEqualTo(expectedIntermediateAssetAmount)), // ); // expect(sellAmount, 'Two hop sell amount').to.bignumber.equal(expectedSellAmount); // }); // }); // });