updated unit tests

This commit is contained in:
David Sun
2019-11-16 11:14:34 -06:00
committed by Jacob Evans
parent e299fa27a0
commit 1135d5a971
8 changed files with 171 additions and 81 deletions

View File

@@ -1,6 +1,7 @@
import { BigNumber } from '@0x/utils';
import {
ExtensionContractType,
ForwarderExtensionContractOpts,
OrderPrunerOpts,
OrderPrunerPermittedFeeTypes,
@@ -8,7 +9,6 @@ import {
SwapQuoteGetOutputOpts,
SwapQuoteRequestOpts,
SwapQuoterOpts,
ExtensionContractType,
} from './types';
const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info';
@@ -18,7 +18,6 @@ const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
const MAINNET_CHAIN_ID = 1;
const ONE_SECOND_MS = 1000;
const DEFAULT_PER_PAGE = 1000;
const PROTOCOL_FEE_MULTIPLIER = 150000;
const DEFAULT_ORDER_PRUNER_OPTS: OrderPrunerOpts = {
expiryBufferMs: 120000, // 2 minutes
@@ -68,6 +67,5 @@ export const constants = {
DEFAULT_FORWARDER_SWAP_QUOTE_EXECUTE_OPTS,
DEFAULT_SWAP_QUOTE_REQUEST_OPTS,
DEFAULT_PER_PAGE,
PROTOCOL_FEE_MULTIPLIER,
NULL_ERC20_ASSET_DATA,
};

View File

@@ -9,7 +9,6 @@ import * as _ from 'lodash';
import { constants } from '../constants';
import {
CalldataInfo,
ForwarderExtensionContractOpts,
ForwarderSmartContractParams,
MarketOperation,
SmartContractParamsInfo,

View File

@@ -20,9 +20,10 @@ import {
MarketSellSwapQuote,
PrunedSignedOrder,
} from '../src/types';
import { ProtocolFeeUtils } from '../src/utils/protocol_fee_utils';
import { chaiSetup } from './utils/chai_setup';
import { getFullyFillableSwapQuoteWithNoFees } from './utils/swap_quote';
import { getFullyFillableSwapQuoteWithNoFeesAsync } from './utils/swap_quote';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
@@ -67,6 +68,8 @@ const expectMakerAndTakerBalancesAsyncFactory = (
};
describe('ExchangeSwapQuoteConsumer', () => {
let contractWrappers: ContractWrappers;
let protocolFeeUtils: ProtocolFeeUtils;
let userAddresses: string[];
let erc20MakerTokenContract: ERC20TokenContract;
let erc20TakerTokenContract: ERC20TokenContract;
@@ -130,6 +133,7 @@ describe('ExchangeSwapQuoteConsumer', () => {
};
const privateKey = devConstants.TESTRPC_PRIVATE_KEYS[userAddresses.indexOf(makerAddress)];
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
protocolFeeUtils = new ProtocolFeeUtils(contractWrappers.exchange);
expectMakerAndTakerBalancesForTakerAssetAsync = expectMakerAndTakerBalancesAsyncFactory(
erc20TakerTokenContract,
makerAddress,
@@ -156,20 +160,22 @@ describe('ExchangeSwapQuoteConsumer', () => {
orders.push(prunedOrder as PrunedSignedOrder);
}
marketSellSwapQuote = getFullyFillableSwapQuoteWithNoFees(
marketSellSwapQuote = await getFullyFillableSwapQuoteWithNoFeesAsync(
makerAssetData,
takerAssetData,
orders,
MarketOperation.Sell,
GAS_PRICE,
protocolFeeUtils,
);
marketBuySwapQuote = getFullyFillableSwapQuoteWithNoFees(
marketBuySwapQuote = await getFullyFillableSwapQuoteWithNoFeesAsync(
makerAssetData,
takerAssetData,
orders,
MarketOperation.Buy,
GAS_PRICE,
protocolFeeUtils,
);
swapQuoteConsumer = new ExchangeSwapQuoteConsumer(provider, contractAddresses, {
@@ -212,7 +218,6 @@ describe('ExchangeSwapQuoteConsumer', () => {
);
await swapQuoteConsumer.executeSwapQuoteOrThrowAsync(marketSellSwapQuote, {
takerAddress,
gasPrice: GAS_PRICE,
gasLimit: 4000000,
});
await expectMakerAndTakerBalancesForMakerAssetAsync(
@@ -235,7 +240,6 @@ describe('ExchangeSwapQuoteConsumer', () => {
);
await swapQuoteConsumer.executeSwapQuoteOrThrowAsync(marketBuySwapQuote, {
takerAddress,
gasPrice: GAS_PRICE,
gasLimit: 4000000,
});
await expectMakerAndTakerBalancesForMakerAssetAsync(

View File

@@ -19,9 +19,10 @@ import {
MarketOperation,
PrunedSignedOrder,
} from '../src/types';
import { ProtocolFeeUtils } from '../src/utils/protocol_fee_utils';
import { chaiSetup } from './utils/chai_setup';
import { getFullyFillableSwapQuoteWithNoFees } from './utils/swap_quote';
import { getFullyFillableSwapQuoteWithNoFeesAsync } from './utils/swap_quote';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
@@ -33,7 +34,7 @@ const ONE_ETH_IN_WEI = new BigNumber(1000000000000000000);
const TESTRPC_CHAIN_ID = devConstants.TESTRPC_CHAIN_ID;
const UNLIMITED_ALLOWANCE_IN_BASE_UNITS = new BigNumber(2).pow(256).minus(1); // tslint:disable-line:custom-no-magic-numbers
const FEE_PERCENTAGE = 0.05;
const PARTIAL_PRUNED_SIGNED_ORDERS_FEELESS: Array<Partial<PrunedSignedOrder>> = [
{
takerAssetAmount: new BigNumber(2).multipliedBy(ONE_ETH_IN_WEI),
@@ -67,7 +68,9 @@ const expectMakerAndTakerBalancesAsyncFactory = (
};
describe('ForwarderSwapQuoteConsumer', () => {
const FEE_PERCENTAGE = 0.05;
let contractWrappers: ContractWrappers;
let protocolFeeUtils: ProtocolFeeUtils;
let erc20Token: ERC20TokenContract;
let userAddresses: string[];
let coinbaseAddress: string;
let makerAddress: string;
@@ -133,6 +136,7 @@ describe('ForwarderSwapQuoteConsumer', () => {
};
const privateKey = devConstants.TESTRPC_PRIVATE_KEYS[userAddresses.indexOf(makerAddress)];
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
protocolFeeUtils = new ProtocolFeeUtils(contractWrappers.exchange);
expectMakerAndTakerBalancesAsync = expectMakerAndTakerBalancesAsyncFactory(
erc20TokenContract,
makerAddress,
@@ -179,28 +183,31 @@ describe('ForwarderSwapQuoteConsumer', () => {
invalidOrders.push(prunedOrder as PrunedSignedOrder);
}
marketSellSwapQuote = getFullyFillableSwapQuoteWithNoFees(
marketSellSwapQuote = await getFullyFillableSwapQuoteWithNoFeesAsync(
makerAssetData,
wethAssetData,
orders,
MarketOperation.Sell,
GAS_PRICE,
protocolFeeUtils,
);
marketBuySwapQuote = getFullyFillableSwapQuoteWithNoFees(
marketBuySwapQuote = await getFullyFillableSwapQuoteWithNoFeesAsync(
makerAssetData,
wethAssetData,
orders,
MarketOperation.Buy,
GAS_PRICE,
protocolFeeUtils,
);
invalidMarketBuySwapQuote = getFullyFillableSwapQuoteWithNoFees(
invalidMarketBuySwapQuote = await getFullyFillableSwapQuoteWithNoFeesAsync(
makerAssetData,
takerAssetData,
invalidOrders,
MarketOperation.Buy,
GAS_PRICE,
protocolFeeUtils,
);
swapQuoteConsumer = new ForwarderSwapQuoteConsumer(provider, contractAddresses, {
@@ -234,7 +241,6 @@ describe('ForwarderSwapQuoteConsumer', () => {
);
await swapQuoteConsumer.executeSwapQuoteOrThrowAsync(marketBuySwapQuote, {
takerAddress,
gasPrice: GAS_PRICE,
gasLimit: 4000000,
ethAmount: new BigNumber(10).multipliedBy(ONE_ETH_IN_WEI),
});

View File

@@ -1,21 +1,28 @@
import { ContractAddresses, ContractWrappers } from '@0x/contract-wrappers';
import { constants as devConstants } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
import 'mocha';
import { ProtocolFeeUtils } from '../src/utils/protocol_fee_utils';
import { swapQuoteCalculator } from '../src/utils/swap_quote_calculator';
import { chaiSetup } from './utils/chai_setup';
import { migrateOnceAsync } from './utils/migrate';
import { testHelpers } from './utils/test_helpers';
import { testOrders } from './utils/test_orders';
import { baseUnitAmount } from './utils/utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const GAS_PRICE = new BigNumber(devConstants.DEFAULT_GAS_PRICE);
const ONE_ETH_IN_WEI = new BigNumber(1000000000000000000);
const TESTRPC_CHAIN_ID = 1337;
const MIXED_TEST_ORDERS = _.concat(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
@@ -25,105 +32,130 @@ const MIXED_TEST_ORDERS = _.concat(
// tslint:disable:max-file-line-count
// tslint:disable:custom-no-magic-numbers
describe('swapQuoteCalculator', () => {
let contractWrappers: ContractWrappers;
let protocolFeeUtils: ProtocolFeeUtils;
let contractAddresses: ContractAddresses;
const chainId = TESTRPC_CHAIN_ID;
before(async () => {
const config = {
chainId,
contractAddresses,
};
contractAddresses = await migrateOnceAsync();
await blockchainLifecycle.startAsync();
contractWrappers = new ContractWrappers(provider, config);
protocolFeeUtils = new ProtocolFeeUtils(contractWrappers.exchange);
});
describe('#calculateMarketSellSwapQuote', () => {
describe('InsufficientLiquidityError', () => {
it('should throw if not enough taker asset liquidity (multiple feeless orders)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketSellSwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
baseUnitAmount(10),
0,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(9));
});
it('should throw if not enough taker asset liquidity (multiple feeless orders with 20% slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketSellSwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
baseUnitAmount(10),
0.2,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(7.5));
});
it('should throw if not enough taker asset liquidity (multiple takerAsset denominated fee orders with no slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketSellSwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET,
baseUnitAmount(20),
0,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(15));
});
it('should throw if not enough taker asset liquidity (multiple takerAsset denominated fee orders with 20% slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketSellSwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET,
baseUnitAmount(20),
0.2,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(12.5));
});
it('should throw if not enough taker asset liquidity (multiple makerAsset denominated fee orders with no slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketSellSwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
baseUnitAmount(10),
0,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(9));
});
it('should throw if not enough taker asset liquidity (multiple makerAsset denominated fee orders with 20% slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketSellSwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
baseUnitAmount(10),
0.2,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(7.5));
});
it('should throw if not enough taker asset liquidity (multiple mixed feeType orders with no slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketSellSwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
MIXED_TEST_ORDERS,
baseUnitAmount(40),
0,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(33));
});
it('should throw if not enough taker asset liquidity (multiple mixed feeTyoe orders with 20% slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketSellSwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
MIXED_TEST_ORDERS,
baseUnitAmount(40),
0.2,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(27.5));
});
});
it('calculates a correct swapQuote with no slippage (feeless orders)', () => {
it('calculates a correct swapQuote with no slippage (feeless orders)', async () => {
const assetSellAmount = baseUnitAmount(0.5);
const slippagePercentage = 0;
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
assetSellAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([testOrders.PRUNED_SIGNED_ORDERS_FEELESS[0]]);
@@ -144,14 +176,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(15, 4),
});
});
it('calculates a correct swapQuote with slippage (feeless orders)', () => {
it('calculates a correct swapQuote with slippage (feeless orders)', async () => {
const assetSellAmount = baseUnitAmount(1);
const slippagePercentage = 0.2;
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
assetSellAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([
@@ -175,14 +208,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(30, 4),
});
});
it('calculates a correct swapQuote with no slippage (takerAsset denominated fee orders)', () => {
it('calculates a correct swapQuote with no slippage (takerAsset denominated fee orders)', async () => {
const assetSellAmount = baseUnitAmount(4);
const slippagePercentage = 0;
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET,
assetSellAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET[0]]);
@@ -203,14 +237,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(15, 4),
});
});
it('calculates a correct swapQuote with slippage (takerAsset denominated fee orders)', () => {
it('calculates a correct swapQuote with slippage (takerAsset denominated fee orders)', async () => {
const assetSellAmount = baseUnitAmount(3);
const slippagePercentage = 0.5;
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET,
assetSellAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([
@@ -234,14 +269,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(30, 4),
});
});
it('calculates a correct swapQuote with no slippage (makerAsset denominated fee orders)', () => {
it('calculates a correct swapQuote with no slippage (makerAsset denominated fee orders)', async () => {
const assetSellAmount = baseUnitAmount(4);
const slippagePercentage = 0;
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
assetSellAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET[0]]);
@@ -262,14 +298,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(15, 4),
});
});
it('calculates a correct swapQuote with slippage (makerAsset denominated fee orders)', () => {
it('calculates a correct swapQuote with slippage (makerAsset denominated fee orders)', async () => {
const assetSellAmount = baseUnitAmount(4);
const slippagePercentage = 0.5;
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketSellSwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
assetSellAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([
@@ -295,105 +332,114 @@ describe('swapQuoteCalculator', () => {
});
});
});
describe('#calculateMarketBuySwapQuote', () => {
describe('#calculateMarketBuySwapQuoteAsync', () => {
describe('InsufficientLiquidityError', () => {
it('should throw if not enough maker asset liquidity (multiple feeless orders)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketBuySwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
baseUnitAmount(12),
0,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(10));
});
it('should throw if not enough taker asset liquidity (multiple feeless orders with 20% slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketBuySwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
baseUnitAmount(10),
0.6,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(6.25));
});
it('should throw if not enough taker asset liquidity (multiple takerAsset denominated fee orders with no slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketBuySwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET,
baseUnitAmount(12),
0,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(10));
});
it('should throw if not enough taker asset liquidity (multiple takerAsset denominated fee orders with 20% slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketBuySwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET,
baseUnitAmount(12),
0.6,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(6.25));
});
it('should throw if not enough taker asset liquidity (multiple makerAsset denominated fee orders with no slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketBuySwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
baseUnitAmount(6),
0,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(5));
});
it('should throw if not enough taker asset liquidity (multiple makerAsset denominated fee orders with 20% slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketBuySwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
baseUnitAmount(6),
0.6,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(3.125));
});
it('should throw if not enough taker asset liquidity (multiple mixed feeType orders with no slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketBuySwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
MIXED_TEST_ORDERS,
baseUnitAmount(40),
0,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(25));
});
it('should throw if not enough taker asset liquidity (multiple mixed feeTyoe orders with 20% slippage)', () => {
const errorFunction = () => {
swapQuoteCalculator.calculateMarketBuySwapQuote(
const errorFunction = async () => {
await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
MIXED_TEST_ORDERS,
baseUnitAmount(40),
0.6,
GAS_PRICE,
protocolFeeUtils,
);
};
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, baseUnitAmount(15.625));
});
});
it('calculates a correct swapQuote with no slippage (feeless orders)', () => {
it('calculates a correct swapQuote with no slippage (feeless orders)', async () => {
const assetBuyAmount = baseUnitAmount(3);
const slippagePercentage = 0;
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
assetBuyAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([testOrders.PRUNED_SIGNED_ORDERS_FEELESS[0]]);
@@ -414,14 +460,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(15, 4),
});
});
it('calculates a correct swapQuote with slippage (feeless orders)', () => {
it('calculates a correct swapQuote with slippage (feeless orders)', async () => {
const assetBuyAmount = baseUnitAmount(5);
const slippagePercentage = 0.5;
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEELESS,
assetBuyAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([
@@ -450,14 +497,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(30, 4),
});
});
it('calculates a correct swapQuote with no slippage (takerAsset denominated fee orders)', () => {
it('calculates a correct swapQuote with no slippage (takerAsset denominated fee orders)', async () => {
const assetBuyAmount = baseUnitAmount(3);
const slippagePercentage = 0;
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET,
assetBuyAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET[0]]);
@@ -478,14 +526,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(15, 4),
});
});
it('calculates a correct swapQuote with slippage (takerAsset denominated fee orders)', () => {
it('calculates a correct swapQuote with slippage (takerAsset denominated fee orders)', async () => {
const assetBuyAmount = baseUnitAmount(5);
const slippagePercentage = 0.5;
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_TAKER_ASSET,
assetBuyAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
const fiveSixthEthInWei = new BigNumber(5)
.div(new BigNumber(6))
@@ -513,14 +562,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(30, 4),
});
});
it('calculates a correct swapQuote with no slippage (makerAsset denominated fee orders)', () => {
it('calculates a correct swapQuote with no slippage (makerAsset denominated fee orders)', async () => {
const assetBuyAmount = baseUnitAmount(1);
const slippagePercentage = 0;
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
assetBuyAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
// test if orders are correct
expect(swapQuote.orders).to.deep.equal([testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET[0]]);
@@ -541,14 +591,15 @@ describe('swapQuoteCalculator', () => {
protocolFeeInEthAmount: baseUnitAmount(15, 4),
});
});
it('calculates a correct swapQuote with slippage (makerAsset denominated fee orders)', () => {
it('calculates a correct swapQuote with slippage (makerAsset denominated fee orders)', async () => {
const assetBuyAmount = baseUnitAmount(2.5);
const slippagePercentage = 0.5;
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
const swapQuote = await swapQuoteCalculator.calculateMarketBuySwapQuoteAsync(
testOrders.PRUNED_SIGNED_ORDERS_FEE_IN_MAKER_ASSET,
assetBuyAmount,
slippagePercentage,
GAS_PRICE,
protocolFeeUtils,
);
const totalTakerAssetAmount = new BigNumber(5)
.div(new BigNumber(6))

View File

@@ -11,9 +11,11 @@ import 'mocha';
import { SwapQuote, SwapQuoteConsumer } from '../src';
import { constants } from '../src/constants';
import { ExtensionContractType, MarketOperation, PrunedSignedOrder } from '../src/types';
import { ProtocolFeeUtils } from '../src/utils/protocol_fee_utils';
import { chaiSetup } from './utils/chai_setup';
import { getFullyFillableSwapQuoteWithNoFees } from './utils/swap_quote';
import { getFullyFillableSwapQuoteWithNoFeesAsync } from './utils/swap_quote';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
@@ -68,6 +70,8 @@ const PARTIAL_LARGE_PRUNED_SIGNED_ORDERS: Array<Partial<PrunedSignedOrder>> = [
describe('swapQuoteConsumerUtils', () => {
let wethContract: WETH9Contract;
let contractWrappers: ContractWrappers;
let protocolFeeUtils: ProtocolFeeUtils;
let userAddresses: string[];
let makerAddress: string;
let takerAddress: string;
@@ -118,6 +122,7 @@ describe('swapQuoteConsumerUtils', () => {
};
const privateKey = devConstants.TESTRPC_PRIVATE_KEYS[userAddresses.indexOf(makerAddress)];
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
protocolFeeUtils = new ProtocolFeeUtils(contractWrappers.exchange);
forwarderOrderFactory = new OrderFactory(privateKey, defaultForwarderOrderParams);
swapQuoteConsumer = new SwapQuoteConsumer(provider, {
@@ -173,28 +178,31 @@ describe('swapQuoteConsumerUtils', () => {
largeForwarderOrders.push(prunedOrder as PrunedSignedOrder);
}
forwarderSwapQuote = getFullyFillableSwapQuoteWithNoFees(
forwarderSwapQuote = await getFullyFillableSwapQuoteWithNoFeesAsync(
makerAssetData,
wethAssetData,
forwarderOrders,
MarketOperation.Sell,
GAS_PRICE,
protocolFeeUtils,
);
largeForwarderSwapQuote = getFullyFillableSwapQuoteWithNoFees(
largeForwarderSwapQuote = await getFullyFillableSwapQuoteWithNoFeesAsync(
makerAssetData,
wethAssetData,
largeForwarderOrders,
MarketOperation.Sell,
GAS_PRICE,
protocolFeeUtils,
);
exchangeSwapQuote = getFullyFillableSwapQuoteWithNoFees(
exchangeSwapQuote = await getFullyFillableSwapQuoteWithNoFeesAsync(
makerAssetData,
takerAssetData,
exchangeOrders,
MarketOperation.Sell,
GAS_PRICE,
protocolFeeUtils,
);
});

View File

@@ -1,10 +1,17 @@
import { constants as devConstants } from '@0x/contracts-test-utils';
import { AcceptedRejectedOrders, Orderbook } from '@0x/orderbook';
import { Web3ProviderEngine } from '@0x/subproviders';
import { APIOrder, AssetPairsItem, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as TypeMoq from 'typemoq';
import { SwapQuoter } from '../../src/swap_quoter';
import { PrunedSignedOrder } from '../../src/types';
import { ProtocolFeeUtils } from '../../src/utils/protocol_fee_utils';
const PROTOCOL_FEE_MULTIPLIER = 150000;
// tslint:disable: max-classes-per-file
class OrderbookClass extends Orderbook {
// tslint:disable-next-line:prefer-function-over-method
@@ -49,6 +56,21 @@ const partiallyMockedSwapQuoter = (provider: Web3ProviderEngine, orderbook: Orde
return mockedSwapQuoter;
};
class ProtocolFeeUtilsClass extends ProtocolFeeUtils {
// tslint:disable-next-line:prefer-function-over-method
public async getProtocolFeeMultiplierAsync(): Promise<BigNumber> {
return Promise.resolve(new BigNumber(PROTOCOL_FEE_MULTIPLIER));
}
// tslint:disable-next-line:prefer-function-over-method
public async getGasPriceEstimationOrThrowAsync(): Promise<BigNumber> {
return Promise.resolve(new BigNumber(devConstants.DEFAULT_GAS_PRICE));
}
}
export const protocolFeeUtilsMock = (): TypeMoq.IMock<ProtocolFeeUtils> => {
return TypeMoq.Mock.ofType(ProtocolFeeUtilsClass, TypeMoq.MockBehavior.Strict);
};
const mockGetPrunedSignedOrdersAsync = (
mockedSwapQuoter: TypeMoq.IMock<SwapQuoter>,
makerAssetData: string,

View File

@@ -4,15 +4,16 @@ import * as _ from 'lodash';
import { constants } from '../../src/constants';
import { MarketOperation, PrunedSignedOrder, SwapQuote } from '../../src/types';
import { protocolFeeUtils } from '../../src/utils/protocol_fee_utils';
import { ProtocolFeeUtils } from '../../src/utils/protocol_fee_utils';
export const getFullyFillableSwapQuoteWithNoFees = (
export const getFullyFillableSwapQuoteWithNoFeesAsync = async (
makerAssetData: string,
takerAssetData: string,
orders: PrunedSignedOrder[],
operation: MarketOperation,
gasPrice: BigNumber,
): SwapQuote => {
protocolFeeUtils: ProtocolFeeUtils,
): Promise<SwapQuote> => {
const makerAssetFillAmount = _.reduce(
orders,
(a: BigNumber, c: SignedOrder) => a.plus(c.makerAssetAmount),
@@ -28,13 +29,14 @@ export const getFullyFillableSwapQuoteWithNoFees = (
feeTakerAssetAmount: constants.ZERO_AMOUNT,
takerAssetAmount: totalTakerAssetAmount,
totalTakerAssetAmount,
protocolFeeInEthAmount: protocolFeeUtils.calculateWorstCaseProtocolFee(orders, gasPrice),
protocolFeeInEthAmount: await protocolFeeUtils.calculateWorstCaseProtocolFeeAsync(orders, gasPrice),
};
const quoteBase = {
makerAssetData,
takerAssetData,
orders,
gasPrice,
bestCaseQuoteInfo: quoteInfo,
worstCaseQuoteInfo: quoteInfo,
};