aboutsummaryrefslogtreecommitdiffstats
path: root/packages/asset-buyer/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/asset-buyer/src')
-rw-r--r--packages/asset-buyer/src/errors.ts22
-rw-r--r--packages/asset-buyer/src/index.ts1
-rw-r--r--packages/asset-buyer/src/types.ts2
-rw-r--r--packages/asset-buyer/src/utils/buy_quote_calculator.ts14
4 files changed, 37 insertions, 2 deletions
diff --git a/packages/asset-buyer/src/errors.ts b/packages/asset-buyer/src/errors.ts
new file mode 100644
index 000000000..ec5fe548c
--- /dev/null
+++ b/packages/asset-buyer/src/errors.ts
@@ -0,0 +1,22 @@
+import { BigNumber } from '@0x/utils';
+
+import { AssetBuyerError } from './types';
+
+/**
+ * Error class representing insufficient asset liquidity
+ */
+export class InsufficientAssetLiquidityError extends Error {
+ /**
+ * The amount availabe to fill (in base units) factoring in slippage.
+ */
+ public amountAvailableToFill: BigNumber;
+ /**
+ * @param amountAvailableToFill The amount availabe to fill (in base units) factoring in slippage
+ */
+ constructor(amountAvailableToFill: BigNumber) {
+ super(AssetBuyerError.InsufficientAssetLiquidity);
+ this.amountAvailableToFill = amountAvailableToFill;
+ // Setting prototype so instanceof works. See https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
+ Object.setPrototypeOf(this, InsufficientAssetLiquidityError.prototype);
+ }
+}
diff --git a/packages/asset-buyer/src/index.ts b/packages/asset-buyer/src/index.ts
index 8418edb42..a42d7e272 100644
--- a/packages/asset-buyer/src/index.ts
+++ b/packages/asset-buyer/src/index.ts
@@ -9,6 +9,7 @@ export { SignedOrder } from '@0x/types';
export { BigNumber } from '@0x/utils';
export { AssetBuyer } from './asset_buyer';
+export { InsufficientAssetLiquidityError } from './errors';
export { BasicOrderProvider } from './order_providers/basic_order_provider';
export { StandardRelayerAPIOrderProvider } from './order_providers/standard_relayer_api_order_provider';
export {
diff --git a/packages/asset-buyer/src/types.ts b/packages/asset-buyer/src/types.ts
index 3b573edca..d5d6be695 100644
--- a/packages/asset-buyer/src/types.ts
+++ b/packages/asset-buyer/src/types.ts
@@ -102,7 +102,7 @@ export interface AssetBuyerOpts {
}
/**
- * Possible errors thrown by an AssetBuyer instance or associated static methods.
+ * Possible error messages thrown by an AssetBuyer instance or associated static methods.
*/
export enum AssetBuyerError {
NoEtherTokenContractFound = 'NO_ETHER_TOKEN_CONTRACT_FOUND',
diff --git a/packages/asset-buyer/src/utils/buy_quote_calculator.ts b/packages/asset-buyer/src/utils/buy_quote_calculator.ts
index b15b880c2..fcded6ab1 100644
--- a/packages/asset-buyer/src/utils/buy_quote_calculator.ts
+++ b/packages/asset-buyer/src/utils/buy_quote_calculator.ts
@@ -3,6 +3,7 @@ import { BigNumber } from '@0x/utils';
import * as _ from 'lodash';
import { constants } from '../constants';
+import { InsufficientAssetLiquidityError } from '../errors';
import { AssetBuyerError, BuyQuote, BuyQuoteInfo, OrdersAndFillableAmounts } from '../types';
import { orderUtils } from './order_utils';
@@ -33,7 +34,18 @@ export const buyQuoteCalculator = {
});
// if we do not have enough orders to cover the desired assetBuyAmount, throw
if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) {
- throw new Error(AssetBuyerError.InsufficientAssetLiquidity);
+ // We needed the amount they requested to buy, plus the amount for slippage
+ const totalAmountRequested = assetBuyAmount.plus(slippageBufferAmount);
+ const amountAbleToFill = totalAmountRequested.minus(remainingFillAmount);
+ // multiplierNeededWithSlippage represents what we need to multiply the assetBuyAmount by
+ // in order to get the total amount needed considering slippage
+ // i.e. if slippagePercent was 0.2 (20%), multiplierNeededWithSlippage would be 1.2
+ const multiplierNeededWithSlippage = new BigNumber(1).plus(slippagePercentage);
+ // Given amountAvailableToFillConsideringSlippage * multiplierNeededWithSlippage = amountAbleToFill
+ // We divide amountUnableToFill by multiplierNeededWithSlippage to determine amountAvailableToFillConsideringSlippage
+ const amountAvailableToFillConsideringSlippage = amountAbleToFill.div(multiplierNeededWithSlippage).floor();
+
+ throw new InsufficientAssetLiquidityError(amountAvailableToFillConsideringSlippage);
}
// if we are not buying ZRX:
// given the orders calculated above, find the fee-orders that cover the desired assetBuyAmount (with slippage)