added testing for generating swap quotes
This commit is contained in:
parent
347c6d02cf
commit
9401bb53e8
@ -358,7 +358,6 @@ function findTakerTokenAmountNeededToBuyZrx(
|
|||||||
order,
|
order,
|
||||||
makerFillAmount,
|
makerFillAmount,
|
||||||
);
|
);
|
||||||
// TODO(dave4506) may remove if this is for affiliate fees (asset-buyer2.0)
|
|
||||||
const extraFeeAmount = remainingFillableMakerAssetAmount.isGreaterThanOrEqualTo(adjustedMakerFillAmount)
|
const extraFeeAmount = remainingFillableMakerAssetAmount.isGreaterThanOrEqualTo(adjustedMakerFillAmount)
|
||||||
? constants.ZERO_AMOUNT
|
? constants.ZERO_AMOUNT
|
||||||
: adjustedMakerFillAmount.minus(makerFillAmount);
|
: adjustedMakerFillAmount.minus(makerFillAmount);
|
||||||
|
@ -16,7 +16,295 @@ const expect = chai.expect;
|
|||||||
|
|
||||||
// tslint:disable:custom-no-magic-numbers
|
// tslint:disable:custom-no-magic-numbers
|
||||||
describe('swapQuoteCalculator', () => {
|
describe('swapQuoteCalculator', () => {
|
||||||
describe('#calculate', () => {
|
describe('#calculateMarketSellSwapQuote', () => {
|
||||||
|
let firstOrder: SignedOrder;
|
||||||
|
let firstRemainingFillAmount: BigNumber;
|
||||||
|
let secondOrder: SignedOrder;
|
||||||
|
let secondRemainingFillAmount: BigNumber;
|
||||||
|
let ordersAndFillableAmounts: OrdersAndFillableAmounts;
|
||||||
|
let smallFeeOrderAndFillableAmount: OrdersAndFillableAmounts;
|
||||||
|
let allFeeOrdersAndFillableAmounts: OrdersAndFillableAmounts;
|
||||||
|
beforeEach(() => {
|
||||||
|
// generate two orders for our desired maker asset
|
||||||
|
// the first order has a rate of 4 makerAsset / WETH with a takerFee of 200 ZRX and has only 200 / 400 makerAsset units left to fill (half fillable)
|
||||||
|
// the second order has a rate of 2 makerAsset / WETH with a takerFee of 100 ZRX and has 200 / 200 makerAsset units left to fill (completely fillable)
|
||||||
|
// generate one order for fees
|
||||||
|
// the fee order has a rate of 1 ZRX / WETH with no taker fee and has 100 ZRX left to fill (completely fillable)
|
||||||
|
firstOrder = orderFactory.createSignedOrderFromPartial({
|
||||||
|
makerAssetAmount: new BigNumber(400),
|
||||||
|
takerAssetAmount: new BigNumber(100),
|
||||||
|
takerFee: new BigNumber(200),
|
||||||
|
});
|
||||||
|
firstRemainingFillAmount = new BigNumber(200);
|
||||||
|
secondOrder = orderFactory.createSignedOrderFromPartial({
|
||||||
|
makerAssetAmount: new BigNumber(200),
|
||||||
|
takerAssetAmount: new BigNumber(100),
|
||||||
|
takerFee: new BigNumber(100),
|
||||||
|
});
|
||||||
|
secondRemainingFillAmount = secondOrder.makerAssetAmount;
|
||||||
|
ordersAndFillableAmounts = {
|
||||||
|
orders: [firstOrder, secondOrder],
|
||||||
|
remainingFillableMakerAssetAmounts: [firstRemainingFillAmount, secondRemainingFillAmount],
|
||||||
|
};
|
||||||
|
const smallFeeOrder = orderFactory.createSignedOrderFromPartial({
|
||||||
|
makerAssetAmount: new BigNumber(100),
|
||||||
|
takerAssetAmount: new BigNumber(100),
|
||||||
|
});
|
||||||
|
smallFeeOrderAndFillableAmount = {
|
||||||
|
orders: [smallFeeOrder],
|
||||||
|
remainingFillableMakerAssetAmounts: [smallFeeOrder.makerAssetAmount],
|
||||||
|
};
|
||||||
|
const largeFeeOrder = orderFactory.createSignedOrderFromPartial({
|
||||||
|
makerAssetAmount: new BigNumber(113),
|
||||||
|
takerAssetAmount: new BigNumber(200),
|
||||||
|
takerFee: new BigNumber(11),
|
||||||
|
});
|
||||||
|
allFeeOrdersAndFillableAmounts = {
|
||||||
|
orders: [smallFeeOrder, largeFeeOrder],
|
||||||
|
remainingFillableMakerAssetAmounts: [
|
||||||
|
smallFeeOrder.makerAssetAmount,
|
||||||
|
largeFeeOrder.makerAssetAmount.minus(largeFeeOrder.takerFee),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
describe('InsufficientLiquidityError', () => {
|
||||||
|
it('should throw if not enough taker asset liquidity (multiple orders)', () => {
|
||||||
|
// we have 150 takerAsset units available to fill but attempt to calculate a quote for 200 takerAsset units
|
||||||
|
const errorFunction = () => {
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
ordersAndFillableAmounts,
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
new BigNumber(200),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(150));
|
||||||
|
});
|
||||||
|
it('should throw if not enough taker asset liquidity (multiple orders with 20% slippage)', () => {
|
||||||
|
// we have 150 takerAsset units available to fill but attempt to calculate a quote for 200 makerAsset units
|
||||||
|
const errorFunction = () => {
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
ordersAndFillableAmounts,
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
new BigNumber(200),
|
||||||
|
0.2,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(125));
|
||||||
|
});
|
||||||
|
it('should throw if not enough taker asset liquidity (multiple orders with 5% slippage)', () => {
|
||||||
|
// we have 150 takerAsset units available to fill but attempt to calculate a quote for 200 makerAsset units
|
||||||
|
const errorFunction = () => {
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
ordersAndFillableAmounts,
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
new BigNumber(200),
|
||||||
|
0.05,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(142));
|
||||||
|
});
|
||||||
|
it('should throw if not enough taker asset liquidity (partially filled order)', () => {
|
||||||
|
const firstOrderAndFillableAmount: OrdersAndFillableAmounts = {
|
||||||
|
orders: [firstOrder],
|
||||||
|
remainingFillableMakerAssetAmounts: [firstRemainingFillAmount],
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorFunction = () => {
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
firstOrderAndFillableAmount,
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
new BigNumber(51),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(50));
|
||||||
|
});
|
||||||
|
it('should throw if not enough taker asset liquidity (completely fillable order)', () => {
|
||||||
|
const completelyFillableOrder = orderFactory.createSignedOrderFromPartial({
|
||||||
|
makerAssetAmount: new BigNumber(123),
|
||||||
|
takerAssetAmount: new BigNumber(80),
|
||||||
|
takerFee: new BigNumber(200),
|
||||||
|
});
|
||||||
|
const completelyFillableOrdersAndFillableAmount: OrdersAndFillableAmounts = {
|
||||||
|
orders: [completelyFillableOrder],
|
||||||
|
remainingFillableMakerAssetAmounts: [completelyFillableOrder.makerAssetAmount],
|
||||||
|
};
|
||||||
|
const errorFunction = () => {
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
completelyFillableOrdersAndFillableAmount,
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
new BigNumber(81),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(80));
|
||||||
|
});
|
||||||
|
it('should throw with 1 amount available if no slippage', () => {
|
||||||
|
const smallOrder = orderFactory.createSignedOrderFromPartial({
|
||||||
|
makerAssetAmount: new BigNumber(1),
|
||||||
|
takerAssetAmount: new BigNumber(1),
|
||||||
|
takerFee: new BigNumber(0),
|
||||||
|
});
|
||||||
|
const errorFunction = () => {
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
{ orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] },
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
new BigNumber(100),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(1));
|
||||||
|
});
|
||||||
|
it('should throw with 0 available to fill if amount rounds to 0', () => {
|
||||||
|
const smallOrder = orderFactory.createSignedOrderFromPartial({
|
||||||
|
makerAssetAmount: new BigNumber(1),
|
||||||
|
takerAssetAmount: new BigNumber(1),
|
||||||
|
takerFee: new BigNumber(0),
|
||||||
|
});
|
||||||
|
const errorFunction = () => {
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
{ orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] },
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
new BigNumber(100),
|
||||||
|
0.2,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(0));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should not throw if order is fillable', () => {
|
||||||
|
expect(() =>
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
ordersAndFillableAmounts,
|
||||||
|
allFeeOrdersAndFillableAmounts,
|
||||||
|
new BigNumber(125),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
).to.not.throw();
|
||||||
|
});
|
||||||
|
it('should throw if not enough ZRX liquidity', () => {
|
||||||
|
// we request 300 makerAsset units but the ZRX order is only enough to fill the first order, which only has 200 makerAssetUnits available
|
||||||
|
expect(() =>
|
||||||
|
swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
ordersAndFillableAmounts,
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
new BigNumber(125),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
).to.throw(SwapQuoterError.InsufficientZrxLiquidity);
|
||||||
|
});
|
||||||
|
it('calculates a correct swapQuote with no slippage', () => {
|
||||||
|
// we request 100 takerAsset units which can be filled using the first order
|
||||||
|
// the first order requires a fee of 100 ZRX from the taker which can be filled by the feeOrder
|
||||||
|
const assetSellAmount = new BigNumber(50);
|
||||||
|
const slippagePercentage = 0;
|
||||||
|
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
ordersAndFillableAmounts,
|
||||||
|
smallFeeOrderAndFillableAmount,
|
||||||
|
assetSellAmount,
|
||||||
|
slippagePercentage,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
// test if orders are correct
|
||||||
|
expect(swapQuote.orders).to.deep.equal([ordersAndFillableAmounts.orders[0]]);
|
||||||
|
expect(swapQuote.feeOrders).to.deep.equal([smallFeeOrderAndFillableAmount.orders[0]]);
|
||||||
|
// test if rates are correct
|
||||||
|
// 50 eth to fill the first order + 100 eth for fees
|
||||||
|
const expectedMakerAssetAmountForTakerAsset = new BigNumber(200);
|
||||||
|
const expectedTakerAssetAmountForZrxFees = new BigNumber(100);
|
||||||
|
const expectedTotalTakerAssetAmount = assetSellAmount.plus(
|
||||||
|
expectedTakerAssetAmountForZrxFees,
|
||||||
|
);
|
||||||
|
expect(swapQuote.bestCaseQuoteInfo.takerTokenAmount).to.bignumber.equal(
|
||||||
|
assetSellAmount,
|
||||||
|
);
|
||||||
|
expect(swapQuote.bestCaseQuoteInfo.makerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedMakerAssetAmountForTakerAsset,
|
||||||
|
);
|
||||||
|
expect(swapQuote.bestCaseQuoteInfo.feeTakerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedTakerAssetAmountForZrxFees,
|
||||||
|
);
|
||||||
|
expect(swapQuote.bestCaseQuoteInfo.totalTakerTokenAmount).to.bignumber.equal(expectedTotalTakerAssetAmount);
|
||||||
|
// because we have no slippage protection, minRate is equal to maxRate
|
||||||
|
expect(swapQuote.worstCaseQuoteInfo.takerTokenAmount).to.bignumber.equal(
|
||||||
|
assetSellAmount,
|
||||||
|
);
|
||||||
|
expect(swapQuote.worstCaseQuoteInfo.makerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedMakerAssetAmountForTakerAsset,
|
||||||
|
);
|
||||||
|
expect(swapQuote.worstCaseQuoteInfo.feeTakerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedTakerAssetAmountForZrxFees,
|
||||||
|
);
|
||||||
|
expect(swapQuote.worstCaseQuoteInfo.totalTakerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedTotalTakerAssetAmount,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('calculates a correct swapQuote with slippage', () => {
|
||||||
|
// we request 50 takerAsset units which can be filled using the first order
|
||||||
|
// however with 50% slippage we are protecting the buy with 25 extra takerAssetUnits
|
||||||
|
// so we need enough orders to fill 75 takerAssetUnits
|
||||||
|
// 150 takerAssetUnits can only be filled using both orders
|
||||||
|
// the first order requires a fee of 100 ZRX from the taker which can be filled by the feeOrder
|
||||||
|
const assetSellAmount = new BigNumber(50);
|
||||||
|
const slippagePercentage = 0.5;
|
||||||
|
const swapQuote = swapQuoteCalculator.calculateMarketSellSwapQuote(
|
||||||
|
ordersAndFillableAmounts,
|
||||||
|
allFeeOrdersAndFillableAmounts,
|
||||||
|
assetSellAmount,
|
||||||
|
slippagePercentage,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
// test if orders are correct
|
||||||
|
expect(swapQuote.orders).to.deep.equal(ordersAndFillableAmounts.orders);
|
||||||
|
expect(swapQuote.feeOrders).to.deep.equal(allFeeOrdersAndFillableAmounts.orders);
|
||||||
|
// test if rates are correct
|
||||||
|
// 50 eth to fill the first order + 100 eth for fees
|
||||||
|
const expectedMakerAssetAmountForTakerAsset = new BigNumber(200);
|
||||||
|
const expectedTakerAssetAmountForZrxFees = new BigNumber(100);
|
||||||
|
const expectedTotalTakerAssetAmount = assetSellAmount.plus(
|
||||||
|
expectedTakerAssetAmountForZrxFees,
|
||||||
|
);
|
||||||
|
expect(swapQuote.bestCaseQuoteInfo.takerTokenAmount).to.bignumber.equal(
|
||||||
|
assetSellAmount,
|
||||||
|
);
|
||||||
|
expect(swapQuote.bestCaseQuoteInfo.makerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedMakerAssetAmountForTakerAsset,
|
||||||
|
);
|
||||||
|
expect(swapQuote.bestCaseQuoteInfo.feeTakerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedTakerAssetAmountForZrxFees,
|
||||||
|
);
|
||||||
|
expect(swapQuote.bestCaseQuoteInfo.totalTakerTokenAmount).to.bignumber.equal(expectedTotalTakerAssetAmount);
|
||||||
|
// 100 eth to fill the first order + 208 eth for fees
|
||||||
|
const expectedWorstMakerAssetAmountForTakerAsset = new BigNumber(100);
|
||||||
|
const expectedWorstTakerAssetAmountForZrxFees = new BigNumber(99);
|
||||||
|
const expectedWorstTotalTakerAssetAmount = assetSellAmount.plus(
|
||||||
|
expectedWorstTakerAssetAmountForZrxFees,
|
||||||
|
);
|
||||||
|
expect(swapQuote.worstCaseQuoteInfo.takerTokenAmount).to.bignumber.equal(
|
||||||
|
assetSellAmount,
|
||||||
|
);
|
||||||
|
expect(swapQuote.worstCaseQuoteInfo.makerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedWorstMakerAssetAmountForTakerAsset,
|
||||||
|
);
|
||||||
|
expect(swapQuote.worstCaseQuoteInfo.feeTakerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedWorstTakerAssetAmountForZrxFees,
|
||||||
|
);
|
||||||
|
expect(swapQuote.worstCaseQuoteInfo.totalTakerTokenAmount).to.bignumber.equal(
|
||||||
|
expectedWorstTotalTakerAssetAmount,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('#calculateMarketBuySwapQuote', () => {
|
||||||
let firstOrder: SignedOrder;
|
let firstOrder: SignedOrder;
|
||||||
let firstRemainingFillAmount: BigNumber;
|
let firstRemainingFillAmount: BigNumber;
|
||||||
let secondOrder: SignedOrder;
|
let secondOrder: SignedOrder;
|
||||||
@ -71,7 +359,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
it('should throw if not enough maker asset liquidity (multiple orders)', () => {
|
it('should throw if not enough maker asset liquidity (multiple orders)', () => {
|
||||||
// we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
|
// we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
|
||||||
const errorFunction = () => {
|
const errorFunction = () => {
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
new BigNumber(500),
|
new BigNumber(500),
|
||||||
@ -84,7 +372,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
it('should throw if not enough maker asset liquidity (multiple orders with 20% slippage)', () => {
|
it('should throw if not enough maker asset liquidity (multiple orders with 20% slippage)', () => {
|
||||||
// we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
|
// we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
|
||||||
const errorFunction = () => {
|
const errorFunction = () => {
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
new BigNumber(500),
|
new BigNumber(500),
|
||||||
@ -97,7 +385,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
it('should throw if not enough maker asset liquidity (multiple orders with 5% slippage)', () => {
|
it('should throw if not enough maker asset liquidity (multiple orders with 5% slippage)', () => {
|
||||||
// we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
|
// we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
|
||||||
const errorFunction = () => {
|
const errorFunction = () => {
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
new BigNumber(600),
|
new BigNumber(600),
|
||||||
@ -114,7 +402,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const errorFunction = () => {
|
const errorFunction = () => {
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
firstOrderAndFillableAmount,
|
firstOrderAndFillableAmount,
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
new BigNumber(201),
|
new BigNumber(201),
|
||||||
@ -135,7 +423,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
remainingFillableMakerAssetAmounts: [completelyFillableOrder.makerAssetAmount],
|
remainingFillableMakerAssetAmounts: [completelyFillableOrder.makerAssetAmount],
|
||||||
};
|
};
|
||||||
const errorFunction = () => {
|
const errorFunction = () => {
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
completelyFillableOrdersAndFillableAmount,
|
completelyFillableOrdersAndFillableAmount,
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
new BigNumber(124),
|
new BigNumber(124),
|
||||||
@ -152,7 +440,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
takerFee: new BigNumber(0),
|
takerFee: new BigNumber(0),
|
||||||
});
|
});
|
||||||
const errorFunction = () => {
|
const errorFunction = () => {
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
{ orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] },
|
{ orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] },
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
new BigNumber(600),
|
new BigNumber(600),
|
||||||
@ -169,7 +457,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
takerFee: new BigNumber(0),
|
takerFee: new BigNumber(0),
|
||||||
});
|
});
|
||||||
const errorFunction = () => {
|
const errorFunction = () => {
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
{ orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] },
|
{ orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] },
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
new BigNumber(600),
|
new BigNumber(600),
|
||||||
@ -182,7 +470,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
});
|
});
|
||||||
it('should not throw if order is fillable', () => {
|
it('should not throw if order is fillable', () => {
|
||||||
expect(() =>
|
expect(() =>
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
allFeeOrdersAndFillableAmounts,
|
allFeeOrdersAndFillableAmounts,
|
||||||
new BigNumber(300),
|
new BigNumber(300),
|
||||||
@ -194,7 +482,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
it('should throw if not enough ZRX liquidity', () => {
|
it('should throw if not enough ZRX liquidity', () => {
|
||||||
// we request 300 makerAsset units but the ZRX order is only enough to fill the first order, which only has 200 makerAssetUnits available
|
// we request 300 makerAsset units but the ZRX order is only enough to fill the first order, which only has 200 makerAssetUnits available
|
||||||
expect(() =>
|
expect(() =>
|
||||||
swapQuoteCalculator.calculate(
|
swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
new BigNumber(300),
|
new BigNumber(300),
|
||||||
@ -208,7 +496,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
// the first order requires a fee of 100 ZRX from the taker which can be filled by the feeOrder
|
// the first order requires a fee of 100 ZRX from the taker which can be filled by the feeOrder
|
||||||
const assetBuyAmount = new BigNumber(200);
|
const assetBuyAmount = new BigNumber(200);
|
||||||
const slippagePercentage = 0;
|
const slippagePercentage = 0;
|
||||||
const swapQuote = swapQuoteCalculator.calculate(
|
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
smallFeeOrderAndFillableAmount,
|
smallFeeOrderAndFillableAmount,
|
||||||
assetBuyAmount,
|
assetBuyAmount,
|
||||||
@ -243,7 +531,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
expectedTotalTakerAssetAmount,
|
expectedTotalTakerAssetAmount,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('calculates a correct swapQuote with with slippage', () => {
|
it('calculates a correct swapQuote with slippage', () => {
|
||||||
// we request 200 makerAsset units which can be filled using the first order
|
// we request 200 makerAsset units which can be filled using the first order
|
||||||
// however with 50% slippage we are protecting the buy with 100 extra makerAssetUnits
|
// however with 50% slippage we are protecting the buy with 100 extra makerAssetUnits
|
||||||
// so we need enough orders to fill 300 makerAssetUnits
|
// so we need enough orders to fill 300 makerAssetUnits
|
||||||
@ -251,7 +539,7 @@ describe('swapQuoteCalculator', () => {
|
|||||||
// the first order requires a fee of 100 ZRX from the taker which can be filled by the feeOrder
|
// the first order requires a fee of 100 ZRX from the taker which can be filled by the feeOrder
|
||||||
const assetBuyAmount = new BigNumber(200);
|
const assetBuyAmount = new BigNumber(200);
|
||||||
const slippagePercentage = 0.5;
|
const slippagePercentage = 0.5;
|
||||||
const swapQuote = swapQuoteCalculator.calculate(
|
const swapQuote = swapQuoteCalculator.calculateMarketBuySwapQuote(
|
||||||
ordersAndFillableAmounts,
|
ordersAndFillableAmounts,
|
||||||
allFeeOrdersAndFillableAmounts,
|
allFeeOrdersAndFillableAmounts,
|
||||||
assetBuyAmount,
|
assetBuyAmount,
|
||||||
|
@ -3,7 +3,7 @@ import { SignedOrder } from '@0x/types';
|
|||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { SwapQuote } from '../../src';
|
import { MarketBuySwapQuote, MarketSellSwapQuote } from '../../src';
|
||||||
|
|
||||||
const ZERO_BIG_NUMBER = new BigNumber(0);
|
const ZERO_BIG_NUMBER = new BigNumber(0);
|
||||||
|
|
||||||
@ -25,11 +25,11 @@ export const getSignedOrdersWithNoFees = (
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getFullyFillableSwapQuoteWithNoFees = (
|
export const getFullyFillableMarketBuySwapQuoteWithNoFees = (
|
||||||
makerAssetData: string,
|
makerAssetData: string,
|
||||||
takerAssetData: string,
|
takerAssetData: string,
|
||||||
orders: SignedOrder[],
|
orders: SignedOrder[],
|
||||||
): SwapQuote => {
|
): MarketBuySwapQuote => {
|
||||||
const makerAssetFillAmount = _.reduce(
|
const makerAssetFillAmount = _.reduce(
|
||||||
orders,
|
orders,
|
||||||
(a: BigNumber, c: SignedOrder) => a.plus(c.makerAssetAmount),
|
(a: BigNumber, c: SignedOrder) => a.plus(c.makerAssetAmount),
|
||||||
@ -41,6 +41,7 @@ export const getFullyFillableSwapQuoteWithNoFees = (
|
|||||||
ZERO_BIG_NUMBER,
|
ZERO_BIG_NUMBER,
|
||||||
);
|
);
|
||||||
const quoteInfo = {
|
const quoteInfo = {
|
||||||
|
makerTokenAmount: makerAssetFillAmount,
|
||||||
takerTokenAmount: totalTakerTokenAmount,
|
takerTokenAmount: totalTakerTokenAmount,
|
||||||
feeTakerTokenAmount: ZERO_BIG_NUMBER,
|
feeTakerTokenAmount: ZERO_BIG_NUMBER,
|
||||||
totalTakerTokenAmount,
|
totalTakerTokenAmount,
|
||||||
@ -56,3 +57,36 @@ export const getFullyFillableSwapQuoteWithNoFees = (
|
|||||||
worstCaseQuoteInfo: quoteInfo,
|
worstCaseQuoteInfo: quoteInfo,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getFullyFillableMarketSellSwapQuoteWithNoFees = (
|
||||||
|
makerAssetData: string,
|
||||||
|
takerAssetData: string,
|
||||||
|
orders: SignedOrder[],
|
||||||
|
): MarketSellSwapQuote => {
|
||||||
|
const makerAssetFillAmount = _.reduce(
|
||||||
|
orders,
|
||||||
|
(a: BigNumber, c: SignedOrder) => a.plus(c.makerAssetAmount),
|
||||||
|
ZERO_BIG_NUMBER,
|
||||||
|
);
|
||||||
|
const totalTakerTokenAmount = _.reduce(
|
||||||
|
orders,
|
||||||
|
(a: BigNumber, c: SignedOrder) => a.plus(c.takerAssetAmount),
|
||||||
|
ZERO_BIG_NUMBER,
|
||||||
|
);
|
||||||
|
const quoteInfo = {
|
||||||
|
makerTokenAmount: makerAssetFillAmount,
|
||||||
|
takerTokenAmount: totalTakerTokenAmount,
|
||||||
|
feeTakerTokenAmount: ZERO_BIG_NUMBER,
|
||||||
|
totalTakerTokenAmount,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
makerAssetData,
|
||||||
|
takerAssetData,
|
||||||
|
orders,
|
||||||
|
feeOrders: [],
|
||||||
|
takerAssetFillAmount: totalTakerTokenAmount,
|
||||||
|
bestCaseQuoteInfo: quoteInfo,
|
||||||
|
worstCaseQuoteInfo: quoteInfo,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user