diff options
Diffstat (limited to 'packages/order-utils/src/order_validation_utils.ts')
-rw-r--r-- | packages/order-utils/src/order_validation_utils.ts | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/packages/order-utils/src/order_validation_utils.ts b/packages/order-utils/src/order_validation_utils.ts index 67d747081..a40069f63 100644 --- a/packages/order-utils/src/order_validation_utils.ts +++ b/packages/order-utils/src/order_validation_utils.ts @@ -1,5 +1,5 @@ -import { RevertReason, SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; +import { RevertReason, SignedOrder } from '@0x/types'; +import { BigNumber } from '@0x/utils'; import { Provider } from 'ethereum-types'; import * as _ from 'lodash'; @@ -9,12 +9,22 @@ import { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_f import { constants } from './constants'; import { ExchangeTransferSimulator } from './exchange_transfer_simulator'; import { orderHashUtils } from './order_hash'; -import { isValidSignatureAsync } from './signature_utils'; +import { signatureUtils } from './signature_utils'; import { utils } from './utils'; +/** + * A utility class for validating orders + */ export class OrderValidationUtils { private readonly _orderFilledCancelledFetcher: AbstractOrderFilledCancelledFetcher; - public static isRoundingError(numerator: BigNumber, denominator: BigNumber, target: BigNumber): boolean { + /** + * A Typescript implementation mirroring the implementation of isRoundingError in the + * Exchange smart contract + * @param numerator Numerator value. When used to check an order, pass in `takerAssetFilledAmount` + * @param denominator Denominator value. When used to check an order, pass in `order.takerAssetAmount` + * @param target Target value. When used to check an order, pass in `order.makerAssetAmount` + */ + public static isRoundingErrorFloor(numerator: BigNumber, denominator: BigNumber, target: BigNumber): boolean { // Solidity's mulmod() in JS // Source: https://solidity.readthedocs.io/en/latest/units-and-global-variables.html#mathematical-and-cryptographic-functions if (denominator.eq(0)) { @@ -31,6 +41,15 @@ export class OrderValidationUtils { const isError = errPercentageTimes1000000.gt(1000); return isError; } + /** + * Validate that the maker & taker have sufficient balances/allowances + * to fill the supplied order to the fillTakerAssetAmount amount + * @param exchangeTradeEmulator ExchangeTradeEmulator to use + * @param signedOrder SignedOrder to test + * @param fillTakerAssetAmount Amount of takerAsset to fill the signedOrder + * @param senderAddress Sender of the fillOrder tx + * @param zrxAssetData AssetData for the ZRX token + */ public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync( exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, @@ -39,7 +58,7 @@ export class OrderValidationUtils { zrxAssetData: string, ): Promise<void> { try { - const fillMakerTokenAmount = utils.getPartialAmount( + const fillMakerTokenAmount = utils.getPartialAmountFloor( fillTakerAssetAmount, signedOrder.takerAssetAmount, signedOrder.makerAssetAmount, @@ -60,7 +79,7 @@ export class OrderValidationUtils { TradeSide.Taker, TransferType.Trade, ); - const makerFeeAmount = utils.getPartialAmount( + const makerFeeAmount = utils.getPartialAmountFloor( fillTakerAssetAmount, signedOrder.takerAssetAmount, signedOrder.makerFee, @@ -73,7 +92,7 @@ export class OrderValidationUtils { TradeSide.Maker, TransferType.Fee, ); - const takerFeeAmount = utils.getPartialAmount( + const takerFeeAmount = utils.getPartialAmountFloor( fillTakerAssetAmount, signedOrder.takerAssetAmount, signedOrder.takerFee, @@ -104,9 +123,22 @@ export class OrderValidationUtils { throw new Error(RevertReason.OrderUnfillable); } } + /** + * Instantiate OrderValidationUtils + * @param orderFilledCancelledFetcher A module that implements the AbstractOrderFilledCancelledFetcher + * @return An instance of OrderValidationUtils + */ constructor(orderFilledCancelledFetcher: AbstractOrderFilledCancelledFetcher) { this._orderFilledCancelledFetcher = orderFilledCancelledFetcher; } + /** + * Validate if the supplied order is fillable, and throw if it isn't + * @param exchangeTradeEmulator ExchangeTradeEmulator instance + * @param signedOrder SignedOrder of interest + * @param zrxAssetData ZRX assetData + * @param expectedFillTakerTokenAmount If supplied, this call will make sure this amount is fillable. + * If it isn't supplied, we check if the order is fillable for a non-zero amount + */ public async validateOrderFillableOrThrowAsync( exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, @@ -132,6 +164,15 @@ export class OrderValidationUtils { zrxAssetData, ); } + /** + * Validate a call to FillOrder and throw if it wouldn't succeed + * @param exchangeTradeEmulator ExchangeTradeEmulator to use + * @param provider Web3 provider to use for JSON RPC requests + * @param signedOrder SignedOrder of interest + * @param fillTakerAssetAmount Amount we'd like to fill the order for + * @param takerAddress The taker of the order + * @param zrxAssetData ZRX asset data + */ public async validateFillOrderThrowIfInvalidAsync( exchangeTradeEmulator: ExchangeTransferSimulator, provider: Provider, @@ -147,7 +188,7 @@ export class OrderValidationUtils { throw new Error(RevertReason.InvalidTakerAmount); } const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - const isValid = await isValidSignatureAsync( + const isValid = await signatureUtils.isValidSignatureAsync( provider, orderHash, signedOrder.signature, @@ -177,7 +218,7 @@ export class OrderValidationUtils { zrxAssetData, ); - const wouldRoundingErrorOccur = OrderValidationUtils.isRoundingError( + const wouldRoundingErrorOccur = OrderValidationUtils.isRoundingErrorFloor( desiredFillTakerTokenAmount, signedOrder.takerAssetAmount, signedOrder.makerAssetAmount, @@ -187,6 +228,15 @@ export class OrderValidationUtils { } return filledTakerTokenAmount; } + /** + * Validate a call to fillOrKillOrder and throw if it would fail + * @param exchangeTradeEmulator ExchangeTradeEmulator to use + * @param provider Web3 provider to use for JSON RPC requests + * @param signedOrder SignedOrder of interest + * @param fillTakerAssetAmount Amount we'd like to fill the order for + * @param takerAddress The taker of the order + * @param zrxAssetData ZRX asset data + */ public async validateFillOrKillOrderThrowIfInvalidAsync( exchangeTradeEmulator: ExchangeTransferSimulator, provider: Provider, |