From 857a35d4f71c1c954033c3b0505250e18be21cfb Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 9 Nov 2018 00:45:48 +0100 Subject: Fix validateOrderFillableOrThrowAsync method so it also checks order signature, cancelled, cancelledUpTo, and throws helpful error messages --- .../src/contract_wrappers/exchange_wrapper.ts | 17 +++++++++++++++++ .../src/fetchers/order_filled_cancelled_fetcher.ts | 16 +++++++++++++--- .../src/schemas/validate_order_fillable_opts_schema.ts | 7 +++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 packages/contract-wrappers/src/schemas/validate_order_fillable_opts_schema.ts (limited to 'packages/contract-wrappers/src') diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts index 2e978f35b..902fc755c 100644 --- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts @@ -5,7 +5,9 @@ import { assetDataUtils, BalanceAndProxyAllowanceLazyStore, ExchangeTransferSimulator, + orderHashUtils, OrderValidationUtils, + signatureUtils, } from '@0x/order-utils'; import { AssetProxyId, Order, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; @@ -18,6 +20,7 @@ import { OrderFilledCancelledFetcher } from '../fetchers/order_filled_cancelled_ import { methodOptsSchema } from '../schemas/method_opts_schema'; import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema'; import { txOptsSchema } from '../schemas/tx_opts_schema'; +import { validateOrderFillableOptsSchema } from '../schemas/validate_order_fillable_opts_schema'; import { BlockRange, EventCallback, @@ -1114,6 +1117,20 @@ export class ExchangeWrapper extends ContractWrapper { signedOrder: SignedOrder, opts: ValidateOrderFillableOpts = {}, ): Promise { + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); + assert.doesConformToSchema('opts', opts, validateOrderFillableOptsSchema); + + const orderHash = await orderHashUtils.getOrderHashHex(signedOrder); + const isValidSignature = await signatureUtils.isValidSignatureAsync( + this._web3Wrapper.getProvider(), + orderHash, + signedOrder.signature, + signedOrder.makerAddress, + ); + if (!isValidSignature) { + throw new Error('INVALID_ORDER_SIGNATURE'); + } + const balanceAllowanceFetcher = new AssetBalanceAndProxyAllowanceFetcher( this._erc20TokenWrapper, this._erc721TokenWrapper, diff --git a/packages/contract-wrappers/src/fetchers/order_filled_cancelled_fetcher.ts b/packages/contract-wrappers/src/fetchers/order_filled_cancelled_fetcher.ts index acf7038fa..5d350916c 100644 --- a/packages/contract-wrappers/src/fetchers/order_filled_cancelled_fetcher.ts +++ b/packages/contract-wrappers/src/fetchers/order_filled_cancelled_fetcher.ts @@ -1,5 +1,6 @@ // tslint:disable:no-unnecessary-type-assertion -import { AbstractOrderFilledCancelledFetcher } from '@0x/order-utils'; +import { AbstractOrderFilledCancelledFetcher, orderHashUtils } from '@0x/order-utils'; +import { SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { BlockParamLiteral } from 'ethereum-types'; @@ -18,9 +19,18 @@ export class OrderFilledCancelledFetcher implements AbstractOrderFilledCancelled }); return filledTakerAmount; } - public async isOrderCancelledAsync(orderHash: string): Promise { + public async isOrderCancelledAsync(signedOrder: SignedOrder): Promise { + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); const isCancelled = await this._exchange.isCancelledAsync(orderHash); - return isCancelled; + const orderEpoch = await this._exchange.getOrderEpochAsync( + signedOrder.makerAddress, + signedOrder.senderAddress, + { + defaultBlock: this._stateLayer, + }, + ); + const isCancelledByOrderEpoch = orderEpoch > signedOrder.salt; + return isCancelled || isCancelledByOrderEpoch; } public getZRXAssetData(): string { const zrxAssetData = this._exchange.getZRXAssetData(); diff --git a/packages/contract-wrappers/src/schemas/validate_order_fillable_opts_schema.ts b/packages/contract-wrappers/src/schemas/validate_order_fillable_opts_schema.ts new file mode 100644 index 000000000..2e111af04 --- /dev/null +++ b/packages/contract-wrappers/src/schemas/validate_order_fillable_opts_schema.ts @@ -0,0 +1,7 @@ +export const validateOrderFillableOptsSchema = { + id: '/ValidateOrderFillableOpts', + properties: { + expectedFillTakerTokenAmount: { $ref: '/wholeNumberSchema' }, + }, + type: 'object', +}; -- cgit v1.2.3 From 1f0ac47bd97b88071a6380a728cfdb1457c2590c Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sat, 10 Nov 2018 00:14:48 +0100 Subject: Move signature validation into OrderValidationUtils.validateOrderFillableOrThrowAsync --- .../src/contract_wrappers/exchange_wrapper.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'packages/contract-wrappers/src') diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts index 902fc755c..d3a4e9098 100644 --- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts @@ -1120,17 +1120,6 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.doesConformToSchema('opts', opts, validateOrderFillableOptsSchema); - const orderHash = await orderHashUtils.getOrderHashHex(signedOrder); - const isValidSignature = await signatureUtils.isValidSignatureAsync( - this._web3Wrapper.getProvider(), - orderHash, - signedOrder.signature, - signedOrder.makerAddress, - ); - if (!isValidSignature) { - throw new Error('INVALID_ORDER_SIGNATURE'); - } - const balanceAllowanceFetcher = new AssetBalanceAndProxyAllowanceFetcher( this._erc20TokenWrapper, this._erc721TokenWrapper, @@ -1141,7 +1130,7 @@ export class ExchangeWrapper extends ContractWrapper { const expectedFillTakerTokenAmountIfExists = opts.expectedFillTakerTokenAmount; const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest); - const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher); + const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher, this._web3Wrapper.getProvider()); await orderValidationUtils.validateOrderFillableOrThrowAsync( exchangeTradeSimulator, signedOrder, @@ -1169,7 +1158,7 @@ export class ExchangeWrapper extends ContractWrapper { const exchangeTradeSimulator = new ExchangeTransferSimulator(balanceAllowanceStore); const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest); - const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher); + const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher, this._web3Wrapper.getProvider()); await orderValidationUtils.validateFillOrderThrowIfInvalidAsync( exchangeTradeSimulator, this._web3Wrapper.getProvider(), -- cgit v1.2.3 From d3592d362e243fb5c320125ed18df34858b6db72 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 11 Nov 2018 13:02:45 +0100 Subject: address linter errors --- packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts | 2 -- 1 file changed, 2 deletions(-) (limited to 'packages/contract-wrappers/src') diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts index d3a4e9098..c76e51eee 100644 --- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts @@ -5,9 +5,7 @@ import { assetDataUtils, BalanceAndProxyAllowanceLazyStore, ExchangeTransferSimulator, - orderHashUtils, OrderValidationUtils, - signatureUtils, } from '@0x/order-utils'; import { AssetProxyId, Order, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; -- cgit v1.2.3