updated unit tests
This commit is contained in:
@@ -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,
|
||||
};
|
||||
|
||||
@@ -9,7 +9,6 @@ import * as _ from 'lodash';
|
||||
import { constants } from '../constants';
|
||||
import {
|
||||
CalldataInfo,
|
||||
ForwarderExtensionContractOpts,
|
||||
ForwarderSmartContractParams,
|
||||
MarketOperation,
|
||||
SmartContractParamsInfo,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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),
|
||||
});
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user