aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-utils')
-rw-r--r--packages/order-utils/src/constants.ts2
-rw-r--r--packages/order-utils/src/market_utils.ts14
-rw-r--r--packages/order-utils/test/market_utils_test.ts162
-rw-r--r--packages/order-utils/test/utils/test_order_factory.ts7
4 files changed, 165 insertions, 20 deletions
diff --git a/packages/order-utils/src/constants.ts b/packages/order-utils/src/constants.ts
index 5137ff499..c23578c20 100644
--- a/packages/order-utils/src/constants.ts
+++ b/packages/order-utils/src/constants.ts
@@ -11,6 +11,6 @@ export const constants = {
ERC721_ASSET_DATA_MINIMUM_BYTE_LENGTH: 53,
SELECTOR_LENGTH: 4,
BASE_16: 16,
- INFINITE_TIMESTAMP_SEC: new BigNumber(2524604400), // Close to infinite,
+ INFINITE_TIMESTAMP_SEC: new BigNumber(2524604400), // Close to infinite
ZERO_AMOUNT: new BigNumber(0),
};
diff --git a/packages/order-utils/src/market_utils.ts b/packages/order-utils/src/market_utils.ts
index d66448a0b..94b5be4eb 100644
--- a/packages/order-utils/src/market_utils.ts
+++ b/packages/order-utils/src/market_utils.ts
@@ -17,7 +17,7 @@ export const marketUtils = {
* You can use OrderStateUtils @0xproject/order-utils to perform blockchain lookups
* for these values.
* @param makerAssetFillAmount The amount of makerAsset desired to be filled.
- * @param slippageBufferAmount An additional amount makerAsset to be covered by the result in case of trade collisions or partial fills.
+ * @param slippageBufferAmount An additional amount of makerAsset to be covered by the result in case of trade collisions or partial fills.
* @return Resulting orders and remaining fill amount that could not be covered by the input.
*/
findOrdersThatCoverMakerAssetFillAmount(
@@ -80,8 +80,8 @@ export const marketUtils = {
* @param remainingFillableFeeAmounts An array of BigNumbers corresponding to the signedFeeOrders parameter.
* You can use OrderStateUtils @0xproject/order-utils to perform blockchain lookups
* for these values.
- * @param slippageBufferAmount An additional amount makerAsset to be covered by the result in case of trade collisions or partial fills.
- * @return Resulting orders and remaining fill amount that could not be covered by the input.
+ * @param slippageBufferAmount An additional amount of fee to be covered by the result in case of trade collisions or partial fills.
+ * @return Resulting orders and remaining fee amount that could not be covered by the input.
*/
findFeeOrdersThatCoverFeesForTargetOrders(
signedOrders: SignedOrder[],
@@ -89,7 +89,7 @@ export const marketUtils = {
signedFeeOrders: SignedOrder[],
remainingFillableFeeAmounts: BigNumber[],
slippageBufferAmount: BigNumber = constants.ZERO_AMOUNT,
- ): { resultOrders: SignedOrder[]; remainingFillAmount: BigNumber } {
+ ): { resultOrders: SignedOrder[]; remainingFeeAmount: BigNumber } {
// type assertions
assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
_.forEach(remainingFillableMakerAssetAmounts, (amount, index) =>
@@ -121,12 +121,16 @@ export const marketUtils = {
},
constants.ZERO_AMOUNT,
);
- return marketUtils.findOrdersThatCoverMakerAssetFillAmount(
+ const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
signedFeeOrders,
remainingFillableFeeAmounts,
totalFeeAmount,
slippageBufferAmount,
);
+ return {
+ resultOrders,
+ remainingFeeAmount: remainingFillAmount,
+ };
// TODO: add more orders here to cover rounding
// https://github.com/0xProject/0x-protocol-specification/blob/master/v2/forwarding-contract-specification.md#over-buying-zrx
},
diff --git a/packages/order-utils/test/market_utils_test.ts b/packages/order-utils/test/market_utils_test.ts
index ac3fb9b93..03f86c581 100644
--- a/packages/order-utils/test/market_utils_test.ts
+++ b/packages/order-utils/test/market_utils_test.ts
@@ -12,7 +12,7 @@ const expect = chai.expect;
// tslint:disable: no-unused-expression
describe('marketUtils', () => {
- describe.only('#findOrdersThatCoverMakerAssetFillAmount', () => {
+ describe('#findOrdersThatCoverMakerAssetFillAmount', () => {
describe('no orders', () => {
it('returns empty and unchanged remainingFillAmount', async () => {
const fillAmount = new BigNumber(10);
@@ -25,15 +25,14 @@ describe('marketUtils', () => {
expect(remainingFillAmount).to.be.bignumber.equal(fillAmount);
});
});
- describe('orders are all completely fillable', () => {
+ describe('orders are completely fillable', () => {
// generate three signed orders each with 10 units of makerAsset, 30 total
- const testOrderCount = 3;
const makerAssetAmount = new BigNumber(10);
const inputOrders = testOrderFactory.generateTestSignedOrders(
{
makerAssetAmount,
},
- testOrderCount,
+ 3,
);
// generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount
const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount];
@@ -95,20 +94,19 @@ describe('marketUtils', () => {
});
describe('orders are partially fillable', () => {
// generate three signed orders each with 10 units of makerAsset, 30 total
- const testOrderCount = 3;
const makerAssetAmount = new BigNumber(10);
const inputOrders = testOrderFactory.generateTestSignedOrders(
{
makerAssetAmount,
},
- testOrderCount,
+ 3,
);
// generate remainingFillableMakerAssetAmounts that cover different partial fill scenarios
// 1. order is completely filled already
// 2. order is partially fillable
// 3. order is completely fillable
const remainingFillableMakerAssetAmounts = [constants.ZERO_AMOUNT, new BigNumber(5), makerAssetAmount];
- it('returns last 2 orders and non-zero remainingFillAmount when trying to fill original makerAssetAmounts', async () => {
+ it('returns last two orders and non-zero remainingFillAmount when trying to fill original makerAssetAmounts', async () => {
// try to fill 30 units of makerAsset
const fillAmount = new BigNumber(30);
const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
@@ -121,5 +119,153 @@ describe('marketUtils', () => {
});
});
});
- describe('#findFeeOrdersThatCoverFeesForTargetOrders', () => {});
+ describe('#findFeeOrdersThatCoverFeesForTargetOrders', () => {
+ // generate three signed fee orders each with 10 units of ZRX, 30 total
+ const zrxAmount = new BigNumber(10);
+ const inputFeeOrders = testOrderFactory.generateTestSignedOrders(
+ {
+ makerAssetAmount: zrxAmount,
+ },
+ 3,
+ );
+ // generate remainingFillableFeeAmounts that equal the zrxAmount
+ const remainingFillableFeeAmounts = [zrxAmount, zrxAmount, zrxAmount];
+ describe('no target orders', () => {
+ it('returns empty and zero remainingFeeAmount', async () => {
+ const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
+ [],
+ [],
+ inputFeeOrders,
+ remainingFillableFeeAmounts,
+ );
+ expect(resultOrders).to.be.empty;
+ expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
+ });
+ });
+ describe('no fee orders', () => {
+ // generate three signed orders each with 10 units of makerAsset, 30 total
+ // each signed order requires 10 units of takerFee
+ const makerAssetAmount = new BigNumber(10);
+ const takerFee = new BigNumber(10);
+ const inputOrders = testOrderFactory.generateTestSignedOrders(
+ {
+ makerAssetAmount,
+ takerFee,
+ },
+ 3,
+ );
+ // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount
+ const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount];
+ it('returns empty and non-zero remainingFeeAmount', async () => {
+ const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
+ inputOrders,
+ remainingFillableMakerAssetAmounts,
+ [],
+ [],
+ );
+ expect(resultOrders).to.be.empty;
+ expect(remainingFeeAmount).to.be.bignumber.equal(new BigNumber(30));
+ });
+ });
+ describe('target orders have no fees', () => {
+ // generate three signed orders each with 10 units of makerAsset, 30 total
+ const makerAssetAmount = new BigNumber(10);
+ const inputOrders = testOrderFactory.generateTestSignedOrders(
+ {
+ makerAssetAmount,
+ },
+ 3,
+ );
+ // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount
+ const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount];
+ it('returns empty and zero remainingFeeAmount', async () => {
+ const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
+ inputOrders,
+ remainingFillableMakerAssetAmounts,
+ inputFeeOrders,
+ remainingFillableFeeAmounts,
+ );
+ expect(resultOrders).to.be.empty;
+ expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
+ });
+ });
+ describe('target orders require fees and are completely fillable', () => {
+ // generate three signed orders each with 10 units of makerAsset, 30 total
+ // each signed order requires 10 units of takerFee
+ const makerAssetAmount = new BigNumber(10);
+ const takerFee = new BigNumber(10);
+ const inputOrders = testOrderFactory.generateTestSignedOrders(
+ {
+ makerAssetAmount,
+ takerFee,
+ },
+ 3,
+ );
+ // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount
+ const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount];
+ it('returns input fee orders and zero remainingFeeAmount', async () => {
+ const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
+ inputOrders,
+ remainingFillableMakerAssetAmounts,
+ inputFeeOrders,
+ remainingFillableFeeAmounts,
+ );
+ expect(resultOrders).to.be.deep.equal(inputFeeOrders);
+ expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
+ });
+ });
+ describe('target orders require fees and are partially fillable', () => {
+ // generate three signed orders each with 10 units of makerAsset, 30 total
+ // each signed order requires 10 units of takerFee
+ const makerAssetAmount = new BigNumber(10);
+ const takerFee = new BigNumber(10);
+ const inputOrders = testOrderFactory.generateTestSignedOrders(
+ {
+ makerAssetAmount,
+ takerFee,
+ },
+ 3,
+ );
+ // generate remainingFillableMakerAssetAmounts that cover different partial fill scenarios
+ // 1. order is completely filled already
+ // 2. order is partially fillable
+ // 3. order is completely fillable
+ const remainingFillableMakerAssetAmounts = [constants.ZERO_AMOUNT, new BigNumber(5), makerAssetAmount];
+ it('returns first two input fee orders and zero remainingFeeAmount', async () => {
+ const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
+ inputOrders,
+ remainingFillableMakerAssetAmounts,
+ inputFeeOrders,
+ remainingFillableFeeAmounts,
+ );
+ expect(resultOrders).to.be.deep.equal([inputFeeOrders[0], inputFeeOrders[1]]);
+ expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
+ });
+ });
+ describe('target orders require more fees than available', () => {
+ // generate three signed orders each with 10 units of makerAsset, 30 total
+ // each signed order requires 20 units of takerFee
+ const makerAssetAmount = new BigNumber(10);
+ const takerFee = new BigNumber(20);
+ const inputOrders = testOrderFactory.generateTestSignedOrders(
+ {
+ makerAssetAmount,
+ takerFee,
+ },
+ 3,
+ );
+ // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount
+ const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount];
+ it('returns input fee orders and non-zero remainingFeeAmount', async () => {
+ const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
+ inputOrders,
+ remainingFillableMakerAssetAmounts,
+ inputFeeOrders,
+ remainingFillableFeeAmounts,
+ );
+ expect(resultOrders).to.be.deep.equal(inputFeeOrders);
+ expect(remainingFeeAmount).to.be.bignumber.equal(new BigNumber(30));
+ });
+ });
+ });
});
diff --git a/packages/order-utils/test/utils/test_order_factory.ts b/packages/order-utils/test/utils/test_order_factory.ts
index 611e777ea..75dc6f1f2 100644
--- a/packages/order-utils/test/utils/test_order_factory.ts
+++ b/packages/order-utils/test/utils/test_order_factory.ts
@@ -5,14 +5,9 @@ import { constants, orderFactory } from '../../src';
const BASE_TEST_ORDER: Order = orderFactory.createOrder(
constants.NULL_ADDRESS,
- constants.NULL_ADDRESS,
- constants.NULL_ADDRESS,
- constants.ZERO_AMOUNT,
constants.ZERO_AMOUNT,
+ constants.NULL_ADDRESS,
constants.ZERO_AMOUNT,
- constants.NULL_BYTES,
- constants.ZERO_AMOUNT,
- constants.NULL_BYTES,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
);