aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-utils/src')
-rw-r--r--packages/order-utils/src/abstract/abstract_balance_and_proxy_allowance_fetcher.ts23
-rw-r--r--packages/order-utils/src/abstract/abstract_balance_and_proxy_allowance_lazy_store.ts11
-rw-r--r--packages/order-utils/src/abstract/abstract_order_filled_cancelled_fetcher.ts23
-rw-r--r--packages/order-utils/src/abstract/abstract_order_filled_cancelled_lazy_store.ts13
-rw-r--r--packages/order-utils/src/assert.ts37
-rw-r--r--packages/order-utils/src/asset_data_utils.ts308
-rw-r--r--packages/order-utils/src/constants.ts109
-rw-r--r--packages/order-utils/src/crypto.ts47
-rw-r--r--packages/order-utils/src/eip712_utils.ts83
-rw-r--r--packages/order-utils/src/exchange_transfer_simulator.ts153
-rw-r--r--packages/order-utils/src/index.ts63
-rw-r--r--packages/order-utils/src/market_utils.ts162
-rw-r--r--packages/order-utils/src/order_factory.ts122
-rw-r--r--packages/order-utils/src/order_hash.ts58
-rw-r--r--packages/order-utils/src/order_state_utils.ts346
-rw-r--r--packages/order-utils/src/order_validation_utils.ts257
-rw-r--r--packages/order-utils/src/parsing_utils.ts27
-rw-r--r--packages/order-utils/src/rate_utils.ts48
-rw-r--r--packages/order-utils/src/remaining_fillable_calculator.ts86
-rw-r--r--packages/order-utils/src/salt.ts18
-rw-r--r--packages/order-utils/src/signature_utils.ts417
-rw-r--r--packages/order-utils/src/sorting_utils.ts54
-rw-r--r--packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts140
-rw-r--r--packages/order-utils/src/store/order_filled_cancelled_lazy_store.ts113
-rw-r--r--packages/order-utils/src/types.ts66
-rw-r--r--packages/order-utils/src/utils.ts22
26 files changed, 0 insertions, 2806 deletions
diff --git a/packages/order-utils/src/abstract/abstract_balance_and_proxy_allowance_fetcher.ts b/packages/order-utils/src/abstract/abstract_balance_and_proxy_allowance_fetcher.ts
deleted file mode 100644
index 13fbf1736..000000000
--- a/packages/order-utils/src/abstract/abstract_balance_and_proxy_allowance_fetcher.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { BigNumber } from '@0x/utils';
-
-/**
- * An abstract class to be implemented in order to use OrderStateUtils. The class that
- * implements this interface must be capable of fetching the balance and proxyAllowance
- * for an Ethereum address and assetData
- */
-export abstract class AbstractBalanceAndProxyAllowanceFetcher {
- /**
- * Get balance of assetData for userAddress
- * @param assetData AssetData for which to fetch the balance
- * @param userAddress Ethereum address for which to fetch the balance
- * @return Balance amount in base units
- */
- public abstract async getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
- /**
- * Get the 0x asset proxy allowance of assetData for userAddress
- * @param assetData AssetData for which to fetch the allowance
- * @param userAddress Ethereum address for which to fetch the allowance
- * @return Allowance amount in base units
- */
- public abstract async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
-}
diff --git a/packages/order-utils/src/abstract/abstract_balance_and_proxy_allowance_lazy_store.ts b/packages/order-utils/src/abstract/abstract_balance_and_proxy_allowance_lazy_store.ts
deleted file mode 100644
index 0a73e92bd..000000000
--- a/packages/order-utils/src/abstract/abstract_balance_and_proxy_allowance_lazy_store.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { BigNumber } from '@0x/utils';
-
-export abstract class AbstractBalanceAndProxyAllowanceLazyStore {
- public abstract async getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
- public abstract async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber>;
- public abstract setBalance(assetData: string, userAddress: string, balance: BigNumber): void;
- public abstract deleteBalance(assetData: string, userAddress: string): void;
- public abstract setProxyAllowance(assetData: string, userAddress: string, proxyAllowance: BigNumber): void;
- public abstract deleteProxyAllowance(assetData: string, userAddress: string): void;
- public abstract deleteAll(): void;
-}
diff --git a/packages/order-utils/src/abstract/abstract_order_filled_cancelled_fetcher.ts b/packages/order-utils/src/abstract/abstract_order_filled_cancelled_fetcher.ts
deleted file mode 100644
index 9e240f9ef..000000000
--- a/packages/order-utils/src/abstract/abstract_order_filled_cancelled_fetcher.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-
-/**
- * An abstract class to be implemented in order to use OrderStateUtils. The class that
- * implements this interface must be capable of fetching the amount filled of an order
- * and whether it's been cancelled.
- */
-export abstract class AbstractOrderFilledCancelledFetcher {
- /**
- * Get the amount of the order's takerToken amount already filled
- * @param orderHash OrderHash of order we are interested in
- * @return FilledTakerAmount
- */
- public abstract async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber>;
- /**
- * Whether an order is cancelled
- * @param orderHash OrderHash of order we are interested in
- * @return Whether or not the order is cancelled
- */
- public abstract async isOrderCancelledAsync(signedOrder: SignedOrder): Promise<boolean>;
- public abstract getZRXAssetData(): string;
-}
diff --git a/packages/order-utils/src/abstract/abstract_order_filled_cancelled_lazy_store.ts b/packages/order-utils/src/abstract/abstract_order_filled_cancelled_lazy_store.ts
deleted file mode 100644
index 186521401..000000000
--- a/packages/order-utils/src/abstract/abstract_order_filled_cancelled_lazy_store.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-
-export abstract class AbstractOrderFilledCancelledLazyStore {
- public abstract async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber>;
- public abstract async getIsCancelledAsync(signedOrder: SignedOrder): Promise<boolean>;
- public abstract setFilledTakerAmount(orderHash: string, balance: BigNumber): void;
- public abstract deleteFilledTakerAmount(orderHash: string): void;
- public abstract setIsCancelled(orderHash: string, isCancelled: boolean): void;
- public abstract deleteIsCancelled(orderHash: string): void;
- public abstract deleteAll(): void;
- public abstract getZRXAssetData(): string;
-}
diff --git a/packages/order-utils/src/assert.ts b/packages/order-utils/src/assert.ts
deleted file mode 100644
index 2f73f58c4..000000000
--- a/packages/order-utils/src/assert.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { assert as sharedAssert } from '@0x/assert';
-// HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here
-// tslint:disable:no-unused-variable
-import { Schema } from '@0x/json-schemas';
-import { ECSignature, SignatureType } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-// tslint:enable:no-unused-variable
-import * as _ from 'lodash';
-
-import { utils } from './utils';
-
-export const assert = {
- ...sharedAssert,
- async isSenderAddressAsync(
- variableName: string,
- senderAddressHex: string,
- web3Wrapper: Web3Wrapper,
- ): Promise<void> {
- sharedAssert.isETHAddressHex(variableName, senderAddressHex);
- const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
- sharedAssert.assert(
- isSenderAddressAvailable,
- `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
- );
- },
- isOneOfExpectedSignatureTypes(signature: string, signatureTypes: SignatureType[]): void {
- sharedAssert.isHexString('signature', signature);
- const signatureTypeIndexIfExists = utils.getSignatureTypeIndexIfExists(signature);
- const isExpectedSignatureType = _.includes(signatureTypes, signatureTypeIndexIfExists);
- if (!isExpectedSignatureType) {
- throw new Error(
- `Unexpected signatureType: ${signatureTypeIndexIfExists}. Valid signature types: ${signatureTypes}`,
- );
- }
- },
-};
diff --git a/packages/order-utils/src/asset_data_utils.ts b/packages/order-utils/src/asset_data_utils.ts
deleted file mode 100644
index f314891e2..000000000
--- a/packages/order-utils/src/asset_data_utils.ts
+++ /dev/null
@@ -1,308 +0,0 @@
-import {
- AssetProxyId,
- ERC20AssetData,
- ERC721AssetData,
- MultiAssetData,
- MultiAssetDataWithRecursiveDecoding,
- SingleAssetData,
-} from '@0x/types';
-import { AbiEncoder, BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-
-import { constants } from './constants';
-
-const encodingRules: AbiEncoder.EncodingRules = { shouldOptimize: true };
-const decodingRules: AbiEncoder.DecodingRules = { shouldConvertStructsToObjects: true };
-
-export const assetDataUtils = {
- /**
- * Encodes an ERC20 token address into a hex encoded assetData string, usable in the makerAssetData or
- * takerAssetData fields in a 0x order.
- * @param tokenAddress The ERC20 token address to encode
- * @return The hex encoded assetData string
- */
- encodeERC20AssetData(tokenAddress: string): string {
- const abiEncoder = new AbiEncoder.Method(constants.ERC20_METHOD_ABI);
- const args = [tokenAddress];
- const assetData = abiEncoder.encode(args, encodingRules);
- return assetData;
- },
- /**
- * Decodes an ERC20 assetData hex string into it's corresponding ERC20 tokenAddress & assetProxyId
- * @param assetData Hex encoded assetData string to decode
- * @return An object containing the decoded tokenAddress & assetProxyId
- */
- decodeERC20AssetData(assetData: string): ERC20AssetData {
- assetDataUtils.assertIsERC20AssetData(assetData);
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- const abiEncoder = new AbiEncoder.Method(constants.ERC20_METHOD_ABI);
- const decodedAssetData = abiEncoder.decode(assetData, decodingRules);
- return {
- assetProxyId,
- // TODO(abandeali1): fix return types for `AbiEncoder.Method.decode` so that we can remove type assertion
- tokenAddress: (decodedAssetData as any).tokenContract,
- };
- },
- /**
- * Encodes an ERC721 token address into a hex encoded assetData string, usable in the makerAssetData or
- * takerAssetData fields in a 0x order.
- * @param tokenAddress The ERC721 token address to encode
- * @param tokenId The ERC721 tokenId to encode
- * @return The hex encoded assetData string
- */
- encodeERC721AssetData(tokenAddress: string, tokenId: BigNumber): string {
- const abiEncoder = new AbiEncoder.Method(constants.ERC721_METHOD_ABI);
- const args = [tokenAddress, tokenId];
- const assetData = abiEncoder.encode(args, encodingRules);
- return assetData;
- },
- /**
- * Decodes an ERC721 assetData hex string into it's corresponding ERC721 tokenAddress, tokenId & assetProxyId
- * @param assetData Hex encoded assetData string to decode
- * @return An object containing the decoded tokenAddress, tokenId & assetProxyId
- */
- decodeERC721AssetData(assetData: string): ERC721AssetData {
- assetDataUtils.assertIsERC721AssetData(assetData);
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- const abiEncoder = new AbiEncoder.Method(constants.ERC721_METHOD_ABI);
- const decodedAssetData = abiEncoder.decode(assetData, decodingRules);
- return {
- assetProxyId,
- // TODO(abandeali1): fix return types for `AbiEncoder.Method.decode` so that we can remove type assertion
- tokenAddress: (decodedAssetData as any).tokenContract,
- tokenId: (decodedAssetData as any).tokenId,
- };
- },
- /**
- * Encodes assetData for multiple AssetProxies into a single hex encoded assetData string, usable in the makerAssetData or
- * takerAssetData fields in a 0x order.
- * @param amounts Amounts of each asset that correspond to a single unit within an order.
- * @param nestedAssetData assetData strings that correspond to a valid assetProxyId.
- * @return The hex encoded assetData string
- */
- encodeMultiAssetData(amounts: BigNumber[], nestedAssetData: string[]): string {
- if (amounts.length !== nestedAssetData.length) {
- throw new Error(
- `Invalid MultiAsset arguments. Expected length of 'amounts' (${
- amounts.length
- }) to equal length of 'nestedAssetData' (${nestedAssetData.length})`,
- );
- }
- _.forEach(nestedAssetData, assetDataElement => assetDataUtils.validateAssetDataOrThrow(assetDataElement));
- const abiEncoder = new AbiEncoder.Method(constants.MULTI_ASSET_METHOD_ABI);
- const args = [amounts, nestedAssetData];
- const assetData = abiEncoder.encode(args, encodingRules);
- return assetData;
- },
- /**
- * Decodes a MultiAsset assetData hex string into it's corresponding amounts and nestedAssetData
- * @param assetData Hex encoded assetData string to decode
- * @return An object containing the decoded amounts and nestedAssetData
- */
- decodeMultiAssetData(assetData: string): MultiAssetData {
- assetDataUtils.assertIsMultiAssetData(assetData);
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- const abiEncoder = new AbiEncoder.Method(constants.MULTI_ASSET_METHOD_ABI);
- const decodedAssetData = abiEncoder.decode(assetData, decodingRules);
- // TODO(abandeali1): fix return types for `AbiEncoder.Method.decode` so that we can remove type assertion
- const amounts = (decodedAssetData as any).amounts;
- const nestedAssetData = (decodedAssetData as any).nestedAssetData;
- if (amounts.length !== nestedAssetData.length) {
- throw new Error(
- `Invalid MultiAsset assetData. Expected length of 'amounts' (${
- amounts.length
- }) to equal length of 'nestedAssetData' (${nestedAssetData.length})`,
- );
- }
- return {
- assetProxyId,
- amounts,
- nestedAssetData,
- };
- },
- /**
- * Decodes a MultiAsset assetData hex string into it's corresponding amounts and decoded nestedAssetData elements (all nested elements are flattened)
- * @param assetData Hex encoded assetData string to decode
- * @return An object containing the decoded amounts and nestedAssetData
- */
- decodeMultiAssetDataRecursively(assetData: string): MultiAssetDataWithRecursiveDecoding {
- const decodedAssetData = assetDataUtils.decodeMultiAssetData(assetData);
- const amounts: any[] = [];
- const decodedNestedAssetData = _.map(
- decodedAssetData.nestedAssetData as string[],
- (nestedAssetDataElement, index) => {
- const decodedNestedAssetDataElement = assetDataUtils.decodeAssetDataOrThrow(nestedAssetDataElement);
- if (decodedNestedAssetDataElement.assetProxyId === AssetProxyId.MultiAsset) {
- const recursivelyDecodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(
- nestedAssetDataElement,
- );
- amounts.push(
- _.map(recursivelyDecodedAssetData.amounts, amountElement =>
- amountElement.times(decodedAssetData.amounts[index]),
- ),
- );
- return recursivelyDecodedAssetData.nestedAssetData;
- } else {
- amounts.push(decodedAssetData.amounts[index]);
- return decodedNestedAssetDataElement as SingleAssetData;
- }
- },
- );
- const flattenedAmounts = _.flattenDeep(amounts);
- const flattenedDecodedNestedAssetData = _.flattenDeep(decodedNestedAssetData);
- return {
- assetProxyId: decodedAssetData.assetProxyId,
- amounts: flattenedAmounts,
- // tslint:disable-next-line:no-unnecessary-type-assertion
- nestedAssetData: flattenedDecodedNestedAssetData as SingleAssetData[],
- };
- },
- /**
- * Decode and return the assetProxyId from the assetData
- * @param assetData Hex encoded assetData string to decode
- * @return The assetProxyId
- */
- decodeAssetProxyId(assetData: string): AssetProxyId {
- if (assetData.length < constants.SELECTOR_CHAR_LENGTH_WITH_PREFIX) {
- throw new Error(
- `Could not decode assetData. Expected length of encoded data to be at least 10. Got ${
- assetData.length
- }`,
- );
- }
- const assetProxyId = assetData.slice(0, constants.SELECTOR_CHAR_LENGTH_WITH_PREFIX);
- if (
- assetProxyId !== AssetProxyId.ERC20 &&
- assetProxyId !== AssetProxyId.ERC721 &&
- assetProxyId !== AssetProxyId.MultiAsset
- ) {
- throw new Error(`Invalid assetProxyId: ${assetProxyId}`);
- }
- return assetProxyId;
- },
- /**
- * Checks if the decoded asset data is valid ERC20 data
- * @param decodedAssetData The decoded asset data to check
- */
- isERC20AssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is ERC20AssetData {
- return decodedAssetData.assetProxyId === AssetProxyId.ERC20;
- },
- /**
- * Checks if the decoded asset data is valid ERC721 data
- * @param decodedAssetData The decoded asset data to check
- */
- isERC721AssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is ERC721AssetData {
- return decodedAssetData.assetProxyId === AssetProxyId.ERC721;
- },
- /**
- * Checks if the decoded asset data is valid MultiAsset data
- * @param decodedAssetData The decoded asset data to check
- */
- isMultiAssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is MultiAssetData {
- return decodedAssetData.assetProxyId === AssetProxyId.MultiAsset;
- },
- /**
- * Throws if the length or assetProxyId are invalid for the ERC20Proxy.
- * @param assetData Hex encoded assetData string
- */
- assertIsERC20AssetData(assetData: string): void {
- if (assetData.length < constants.ERC20_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX) {
- throw new Error(
- `Could not decode ERC20 Proxy Data. Expected length of encoded data to be at least ${
- constants.ERC20_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX
- }. Got ${assetData.length}`,
- );
- }
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- if (assetProxyId !== AssetProxyId.ERC20) {
- throw new Error(
- `Could not decode ERC20 assetData. Expected assetProxyId to be ERC20 (${
- AssetProxyId.ERC20
- }), but got ${assetProxyId}`,
- );
- }
- },
- /**
- * Throws if the length or assetProxyId are invalid for the ERC721Proxy.
- * @param assetData Hex encoded assetData string
- */
- assertIsERC721AssetData(assetData: string): void {
- if (assetData.length < constants.ERC721_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX) {
- throw new Error(
- `Could not decode ERC721 assetData. Expected length of encoded data to be at least ${
- constants.ERC721_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX
- }. Got ${assetData.length}`,
- );
- }
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- if (assetProxyId !== AssetProxyId.ERC721) {
- throw new Error(
- `Could not decode ERC721 assetData. Expected assetProxyId to be ERC721 (${
- AssetProxyId.ERC721
- }), but got ${assetProxyId}`,
- );
- }
- },
- /**
- * Throws if the length or assetProxyId are invalid for the MultiAssetProxy.
- * @param assetData Hex encoded assetData string
- */
- assertIsMultiAssetData(assetData: string): void {
- if (assetData.length < constants.MULTI_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX) {
- throw new Error(
- `Could not decode MultiAsset assetData. Expected length of encoded data to be at least ${
- constants.MULTI_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX
- }. Got ${assetData.length}`,
- );
- }
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- if (assetProxyId !== AssetProxyId.MultiAsset) {
- throw new Error(
- `Could not decode MultiAsset assetData. Expected assetProxyId to be MultiAsset (${
- AssetProxyId.MultiAsset
- }), but got ${assetProxyId}`,
- );
- }
- },
- /**
- * Throws if the length or assetProxyId are invalid for the corresponding AssetProxy.
- * @param assetData Hex encoded assetData string
- */
- validateAssetDataOrThrow(assetData: string): void {
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- switch (assetProxyId) {
- case AssetProxyId.ERC20:
- assetDataUtils.assertIsERC20AssetData(assetData);
- break;
- case AssetProxyId.ERC721:
- assetDataUtils.assertIsERC721AssetData(assetData);
- break;
- case AssetProxyId.MultiAsset:
- assetDataUtils.assertIsMultiAssetData(assetData);
- break;
- default:
- throw new Error(`Unrecognized asset proxy id: ${assetProxyId}`);
- }
- },
- /**
- * Decode any assetData into it's corresponding assetData object
- * @param assetData Hex encoded assetData string to decode
- * @return Either a ERC20 or ERC721 assetData object
- */
- decodeAssetDataOrThrow(assetData: string): SingleAssetData | MultiAssetData {
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- switch (assetProxyId) {
- case AssetProxyId.ERC20:
- const erc20AssetData = assetDataUtils.decodeERC20AssetData(assetData);
- return erc20AssetData;
- case AssetProxyId.ERC721:
- const erc721AssetData = assetDataUtils.decodeERC721AssetData(assetData);
- return erc721AssetData;
- case AssetProxyId.MultiAsset:
- const multiAssetData = assetDataUtils.decodeMultiAssetData(assetData);
- return multiAssetData;
- default:
- throw new Error(`Unrecognized asset proxy id: ${assetProxyId}`);
- }
- },
-};
diff --git a/packages/order-utils/src/constants.ts b/packages/order-utils/src/constants.ts
deleted file mode 100644
index a9a687719..000000000
--- a/packages/order-utils/src/constants.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import { MethodAbi } from 'ethereum-types';
-
-const ERC20_METHOD_ABI: MethodAbi = {
- constant: false,
- inputs: [
- {
- name: 'tokenContract',
- type: 'address',
- },
- ],
- name: 'ERC20Token',
- outputs: [],
- payable: false,
- stateMutability: 'nonpayable',
- type: 'function',
-};
-
-const ERC721_METHOD_ABI: MethodAbi = {
- constant: false,
- inputs: [
- {
- name: 'tokenContract',
- type: 'address',
- },
- {
- name: 'tokenId',
- type: 'uint256',
- },
- ],
- name: 'ERC721Token',
- outputs: [],
- payable: false,
- stateMutability: 'nonpayable',
- type: 'function',
-};
-
-const MULTI_ASSET_METHOD_ABI: MethodAbi = {
- constant: false,
- inputs: [
- {
- name: 'amounts',
- type: 'uint256[]',
- },
- {
- name: 'nestedAssetData',
- type: 'bytes[]',
- },
- ],
- name: 'MultiAsset',
- outputs: [],
- payable: false,
- stateMutability: 'nonpayable',
- type: 'function',
-};
-
-export const constants = {
- NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
- NULL_BYTES: '0x',
- NULL_ERC20_ASSET_DATA: '0xf47261b00000000000000000000000000000000000000000000000000000000000000000',
- // tslint:disable-next-line:custom-no-magic-numbers
- UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
- TESTRPC_NETWORK_ID: 50,
- ADDRESS_LENGTH: 20,
- ERC20_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX: 74,
- ERC721_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX: 136,
- MULTI_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX: 266,
- SELECTOR_CHAR_LENGTH_WITH_PREFIX: 10,
- INFINITE_TIMESTAMP_SEC: new BigNumber(2524604400), // Close to infinite
- ZERO_AMOUNT: new BigNumber(0),
- EIP712_DOMAIN_NAME: '0x Protocol',
- EIP712_DOMAIN_VERSION: '2',
- EIP712_DOMAIN_SCHEMA: {
- name: 'EIP712Domain',
- parameters: [
- { name: 'name', type: 'string' },
- { name: 'version', type: 'string' },
- { name: 'verifyingContract', type: 'address' },
- ],
- },
- EIP712_ORDER_SCHEMA: {
- name: 'Order',
- parameters: [
- { name: 'makerAddress', type: 'address' },
- { name: 'takerAddress', type: 'address' },
- { name: 'feeRecipientAddress', type: 'address' },
- { name: 'senderAddress', type: 'address' },
- { name: 'makerAssetAmount', type: 'uint256' },
- { name: 'takerAssetAmount', type: 'uint256' },
- { name: 'makerFee', type: 'uint256' },
- { name: 'takerFee', type: 'uint256' },
- { name: 'expirationTimeSeconds', type: 'uint256' },
- { name: 'salt', type: 'uint256' },
- { name: 'makerAssetData', type: 'bytes' },
- { name: 'takerAssetData', type: 'bytes' },
- ],
- },
- EIP712_ZEROEX_TRANSACTION_SCHEMA: {
- name: 'ZeroExTransaction',
- parameters: [
- { name: 'salt', type: 'uint256' },
- { name: 'signerAddress', type: 'address' },
- { name: 'data', type: 'bytes' },
- ],
- },
- ERC20_METHOD_ABI,
- ERC721_METHOD_ABI,
- MULTI_ASSET_METHOD_ABI,
-};
diff --git a/packages/order-utils/src/crypto.ts b/packages/order-utils/src/crypto.ts
deleted file mode 100644
index 8b835ff48..000000000
--- a/packages/order-utils/src/crypto.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import BN = require('bn.js');
-import ABI = require('ethereumjs-abi');
-import ethUtil = require('ethereumjs-util');
-import * as _ from 'lodash';
-
-export const crypto = {
- /**
- * We convert types from JS to Solidity as follows:
- * BigNumber -> uint256
- * number -> uint8
- * string -> string
- * boolean -> bool
- * valid Ethereum address -> address
- */
- solSHA3(args: any[]): Buffer {
- return crypto._solHash(args, ABI.soliditySHA3);
- },
- solSHA256(args: any[]): Buffer {
- return crypto._solHash(args, ABI.soliditySHA256);
- },
- _solHash(args: any[], hashFunction: (types: string[], values: any[]) => Buffer): Buffer {
- const argTypes: string[] = [];
- _.each(args, (arg, i) => {
- const isNumber = _.isFinite(arg);
- if (isNumber) {
- argTypes.push('uint8');
- } else if (BigNumber.isBigNumber(arg)) {
- argTypes.push('uint256');
- const base = 10;
- args[i] = new BN(arg.toString(base), base);
- } else if (ethUtil.isValidAddress(arg)) {
- argTypes.push('address');
- } else if (_.isString(arg)) {
- argTypes.push('string');
- } else if (_.isBuffer(arg) || _.isTypedArray(arg)) {
- argTypes.push('bytes');
- } else if (_.isBoolean(arg)) {
- argTypes.push('bool');
- } else {
- throw new Error(`Unable to guess arg type: ${arg}`);
- }
- });
- const hash = hashFunction(argTypes, args);
- return hash;
- },
-};
diff --git a/packages/order-utils/src/eip712_utils.ts b/packages/order-utils/src/eip712_utils.ts
deleted file mode 100644
index 385fda989..000000000
--- a/packages/order-utils/src/eip712_utils.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-import { assert } from '@0x/assert';
-import { schemas } from '@0x/json-schemas';
-import { EIP712Object, EIP712TypedData, EIP712Types, Order, ZeroExTransaction } from '@0x/types';
-import * as _ from 'lodash';
-
-import { constants } from './constants';
-
-export const eip712Utils = {
- /**
- * Creates a EIP712TypedData object specific to the 0x protocol for use with signTypedData.
- * @param primaryType The primary type found in message
- * @param types The additional types for the data in message
- * @param message The contents of the message
- * @param exchangeAddress The address of the exchange contract
- * @return A typed data object
- */
- createTypedData: (
- primaryType: string,
- types: EIP712Types,
- message: EIP712Object,
- exchangeAddress: string,
- ): EIP712TypedData => {
- assert.isETHAddressHex('exchangeAddress', exchangeAddress);
- assert.isString('primaryType', primaryType);
- const typedData = {
- types: {
- EIP712Domain: constants.EIP712_DOMAIN_SCHEMA.parameters,
- ...types,
- },
- domain: {
- name: constants.EIP712_DOMAIN_NAME,
- version: constants.EIP712_DOMAIN_VERSION,
- verifyingContract: exchangeAddress,
- },
- message,
- primaryType,
- };
- assert.doesConformToSchema('typedData', typedData, schemas.eip712TypedDataSchema);
- return typedData;
- },
- /**
- * Creates an Order EIP712TypedData object for use with signTypedData.
- * @param Order the order
- * @return A typed data object
- */
- createOrderTypedData: (order: Order): EIP712TypedData => {
- assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
- const normalizedOrder = _.mapValues(order, value => {
- return !_.isString(value) ? value.toString() : value;
- });
- const typedData = eip712Utils.createTypedData(
- constants.EIP712_ORDER_SCHEMA.name,
- { Order: constants.EIP712_ORDER_SCHEMA.parameters },
- normalizedOrder,
- order.exchangeAddress,
- );
- return typedData;
- },
- /**
- * Creates an ExecuteTransaction EIP712TypedData object for use with signTypedData and
- * 0x Exchange executeTransaction.
- * @param ZeroExTransaction the 0x transaction
- * @param exchangeAddress The address of the exchange contract
- * @return A typed data object
- */
- createZeroExTransactionTypedData: (
- zeroExTransaction: ZeroExTransaction,
- exchangeAddress: string,
- ): EIP712TypedData => {
- assert.isETHAddressHex('exchangeAddress', exchangeAddress);
- assert.doesConformToSchema('zeroExTransaction', zeroExTransaction, schemas.zeroExTransactionSchema);
- const normalizedTransaction = _.mapValues(zeroExTransaction, value => {
- return !_.isString(value) ? value.toString() : value;
- });
- const typedData = eip712Utils.createTypedData(
- constants.EIP712_ZEROEX_TRANSACTION_SCHEMA.name,
- { ZeroExTransaction: constants.EIP712_ZEROEX_TRANSACTION_SCHEMA.parameters },
- normalizedTransaction,
- exchangeAddress,
- );
- return typedData;
- },
-};
diff --git a/packages/order-utils/src/exchange_transfer_simulator.ts b/packages/order-utils/src/exchange_transfer_simulator.ts
deleted file mode 100644
index 922ae8e17..000000000
--- a/packages/order-utils/src/exchange_transfer_simulator.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-import { AssetProxyId, ExchangeContractErrs } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-
-import { AbstractBalanceAndProxyAllowanceLazyStore } from './abstract/abstract_balance_and_proxy_allowance_lazy_store';
-import { assetDataUtils } from './asset_data_utils';
-import { constants } from './constants';
-import { TradeSide, TransferType } from './types';
-
-enum FailureReason {
- Balance = 'balance',
- ProxyAllowance = 'proxyAllowance',
-}
-
-const ERR_MSG_MAPPING = {
- [FailureReason.Balance]: {
- [TradeSide.Maker]: {
- [TransferType.Trade]: ExchangeContractErrs.InsufficientMakerBalance,
- [TransferType.Fee]: ExchangeContractErrs.InsufficientMakerFeeBalance,
- },
- [TradeSide.Taker]: {
- [TransferType.Trade]: ExchangeContractErrs.InsufficientTakerBalance,
- [TransferType.Fee]: ExchangeContractErrs.InsufficientTakerFeeBalance,
- },
- },
- [FailureReason.ProxyAllowance]: {
- [TradeSide.Maker]: {
- [TransferType.Trade]: ExchangeContractErrs.InsufficientMakerAllowance,
- [TransferType.Fee]: ExchangeContractErrs.InsufficientMakerFeeAllowance,
- },
- [TradeSide.Taker]: {
- [TransferType.Trade]: ExchangeContractErrs.InsufficientTakerAllowance,
- [TransferType.Fee]: ExchangeContractErrs.InsufficientTakerFeeAllowance,
- },
- },
-};
-
-/**
- * An exchange transfer simulator which simulates asset transfers exactly how the
- * 0x exchange contract would do them.
- */
-export class ExchangeTransferSimulator {
- private readonly _store: AbstractBalanceAndProxyAllowanceLazyStore;
- private static _throwValidationError(
- failureReason: FailureReason,
- tradeSide: TradeSide,
- transferType: TransferType,
- ): never {
- const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
- throw new Error(errMsg);
- }
- /**
- * Instantiate a ExchangeTransferSimulator
- * @param store A class that implements AbstractBalanceAndProxyAllowanceLazyStore
- * @return an instance of ExchangeTransferSimulator
- */
- constructor(store: AbstractBalanceAndProxyAllowanceLazyStore) {
- this._store = store;
- }
- /**
- * Simulates transferFrom call performed by a proxy
- * @param assetData Data of the asset being transferred. Includes
- * it's identifying information and assetType,
- * e.g address for ERC20, address & tokenId for ERC721
- * @param from Owner of the transferred tokens
- * @param to Recipient of the transferred tokens
- * @param amountInBaseUnits The amount of tokens being transferred
- * @param tradeSide Is Maker/Taker transferring
- * @param transferType Is it a fee payment or a value transfer
- */
- public async transferFromAsync(
- assetData: string,
- from: string,
- to: string,
- amountInBaseUnits: BigNumber,
- tradeSide: TradeSide,
- transferType: TransferType,
- ): Promise<void> {
- const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
- switch (assetProxyId) {
- case AssetProxyId.ERC20:
- case AssetProxyId.ERC721:
- // HACK: When simulating an open order (e.g taker is NULL_ADDRESS), we don't want to adjust balances/
- // allowances for the taker. We do however, want to increase the balance of the maker since the maker
- // might be relying on those funds to fill subsequent orders or pay the order's fees.
- if (from === constants.NULL_ADDRESS && tradeSide === TradeSide.Taker) {
- await this._increaseBalanceAsync(assetData, to, amountInBaseUnits);
- return;
- }
- const balance = await this._store.getBalanceAsync(assetData, from);
- const proxyAllowance = await this._store.getProxyAllowanceAsync(assetData, from);
- if (proxyAllowance.isLessThan(amountInBaseUnits)) {
- ExchangeTransferSimulator._throwValidationError(
- FailureReason.ProxyAllowance,
- tradeSide,
- transferType,
- );
- }
- if (balance.isLessThan(amountInBaseUnits)) {
- ExchangeTransferSimulator._throwValidationError(FailureReason.Balance, tradeSide, transferType);
- }
- await this._decreaseProxyAllowanceAsync(assetData, from, amountInBaseUnits);
- await this._decreaseBalanceAsync(assetData, from, amountInBaseUnits);
- await this._increaseBalanceAsync(assetData, to, amountInBaseUnits);
- break;
- case AssetProxyId.MultiAsset:
- const decodedAssetData = assetDataUtils.decodeMultiAssetData(assetData);
- for (const [index, nestedAssetDataElement] of decodedAssetData.nestedAssetData.entries()) {
- const amountsElement = decodedAssetData.amounts[index];
- const totalAmount = amountInBaseUnits.times(amountsElement);
- await this.transferFromAsync(
- nestedAssetDataElement,
- from,
- to,
- totalAmount,
- tradeSide,
- transferType,
- );
- }
- break;
- default:
- break;
- }
- }
- private async _decreaseProxyAllowanceAsync(
- assetData: string,
- userAddress: string,
- amountInBaseUnits: BigNumber,
- ): Promise<void> {
- const proxyAllowance = await this._store.getProxyAllowanceAsync(assetData, userAddress);
- // HACK: This code assumes that all tokens with an UNLIMITED_ALLOWANCE_IN_BASE_UNITS set,
- // are UnlimitedAllowanceTokens. This is however not true, it just so happens that all
- // DummyERC20Tokens we use in tests are.
- if (!proxyAllowance.eq(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
- this._store.setProxyAllowance(assetData, userAddress, proxyAllowance.minus(amountInBaseUnits));
- }
- }
- private async _increaseBalanceAsync(
- assetData: string,
- userAddress: string,
- amountInBaseUnits: BigNumber,
- ): Promise<void> {
- const balance = await this._store.getBalanceAsync(assetData, userAddress);
- this._store.setBalance(assetData, userAddress, balance.plus(amountInBaseUnits));
- }
- private async _decreaseBalanceAsync(
- assetData: string,
- userAddress: string,
- amountInBaseUnits: BigNumber,
- ): Promise<void> {
- const balance = await this._store.getBalanceAsync(assetData, userAddress);
- this._store.setBalance(assetData, userAddress, balance.minus(amountInBaseUnits));
- }
-}
diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts
deleted file mode 100644
index 2150a02e4..000000000
--- a/packages/order-utils/src/index.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-export { orderHashUtils } from './order_hash';
-export { signatureUtils } from './signature_utils';
-export { generatePseudoRandomSalt } from './salt';
-export { assetDataUtils } from './asset_data_utils';
-export { marketUtils } from './market_utils';
-export { rateUtils } from './rate_utils';
-export { sortingUtils } from './sorting_utils';
-export { orderParsingUtils } from './parsing_utils';
-
-export { OrderStateUtils } from './order_state_utils';
-export { AbstractBalanceAndProxyAllowanceFetcher } from './abstract/abstract_balance_and_proxy_allowance_fetcher';
-export { AbstractBalanceAndProxyAllowanceLazyStore } from './abstract/abstract_balance_and_proxy_allowance_lazy_store';
-export { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_filled_cancelled_fetcher';
-export { AbstractOrderFilledCancelledLazyStore } from './abstract/abstract_order_filled_cancelled_lazy_store';
-
-export { OrderValidationUtils } from './order_validation_utils';
-export { ExchangeTransferSimulator } from './exchange_transfer_simulator';
-export { BalanceAndProxyAllowanceLazyStore } from './store/balance_and_proxy_allowance_lazy_store';
-export { OrderFilledCancelledLazyStore } from './store/order_filled_cancelled_lazy_store';
-
-export { eip712Utils } from './eip712_utils';
-
-export {
- Provider,
- JSONRPCRequestPayload,
- JSONRPCErrorCallback,
- JSONRPCResponsePayload,
- JSONRPCResponseError,
-} from 'ethereum-types';
-
-export {
- SignedOrder,
- Order,
- OrderRelevantState,
- OrderState,
- ECSignature,
- SingleAssetData,
- ERC20AssetData,
- ERC721AssetData,
- MultiAssetData,
- MultiAssetDataWithRecursiveDecoding,
- AssetProxyId,
- SignatureType,
- ObjectMap,
- OrderStateValid,
- OrderStateInvalid,
- ExchangeContractErrs,
- EIP712Parameter,
- EIP712TypedData,
- EIP712Types,
- EIP712Object,
- EIP712ObjectValue,
- ZeroExTransaction,
-} from '@0x/types';
-export {
- OrderError,
- TradeSide,
- TransferType,
- FindFeeOrdersThatCoverFeesForTargetOrdersOpts,
- FindOrdersThatCoverMakerAssetFillAmountOpts,
- FeeOrdersAndRemainingFeeAmount,
- OrdersAndRemainingFillAmount,
-} from './types';
diff --git a/packages/order-utils/src/market_utils.ts b/packages/order-utils/src/market_utils.ts
deleted file mode 100644
index 9042551fa..000000000
--- a/packages/order-utils/src/market_utils.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-import { schemas } from '@0x/json-schemas';
-import { Order } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-
-import { assert } from './assert';
-import { constants } from './constants';
-import {
- FeeOrdersAndRemainingFeeAmount,
- FindFeeOrdersThatCoverFeesForTargetOrdersOpts,
- FindOrdersThatCoverMakerAssetFillAmountOpts,
- OrdersAndRemainingFillAmount,
-} from './types';
-
-export const marketUtils = {
- /**
- * Takes an array of orders and returns a subset of those orders that has enough makerAssetAmount
- * in order to fill the input makerAssetFillAmount plus slippageBufferAmount. Iterates from first order to last order.
- * Sort the input by ascending rate in order to get the subset of orders that will cost the least ETH.
- * @param orders An array of objects that extend the Order interface. All orders should specify the same makerAsset.
- * All orders should specify WETH as the takerAsset.
- * @param makerAssetFillAmount The amount of makerAsset desired to be filled.
- * @param opts Optional arguments this function accepts.
- * @return Resulting orders and remaining fill amount that could not be covered by the input.
- */
- findOrdersThatCoverMakerAssetFillAmount<T extends Order>(
- orders: T[],
- makerAssetFillAmount: BigNumber,
- opts?: FindOrdersThatCoverMakerAssetFillAmountOpts,
- ): OrdersAndRemainingFillAmount<T> {
- assert.doesConformToSchema('orders', orders, schemas.ordersSchema);
- assert.isValidBaseUnitAmount('makerAssetFillAmount', makerAssetFillAmount);
- // try to get remainingFillableMakerAssetAmounts from opts, if it's not there, use makerAssetAmount values from orders
- const remainingFillableMakerAssetAmounts = _.get(
- opts,
- 'remainingFillableMakerAssetAmounts',
- _.map(orders, order => order.makerAssetAmount),
- ) as BigNumber[];
- _.forEach(remainingFillableMakerAssetAmounts, (amount, index) =>
- assert.isValidBaseUnitAmount(`remainingFillableMakerAssetAmount[${index}]`, amount),
- );
- assert.assert(
- orders.length === remainingFillableMakerAssetAmounts.length,
- 'Expected orders.length to equal opts.remainingFillableMakerAssetAmounts.length',
- );
- // try to get slippageBufferAmount from opts, if it's not there, default to 0
- const slippageBufferAmount = _.get(opts, 'slippageBufferAmount', constants.ZERO_AMOUNT) as BigNumber;
- assert.isValidBaseUnitAmount('opts.slippageBufferAmount', slippageBufferAmount);
- // calculate total amount of makerAsset needed to be filled
- const totalFillAmount = makerAssetFillAmount.plus(slippageBufferAmount);
- // iterate through the orders input from left to right until we have enough makerAsset to fill totalFillAmount
- const result = _.reduce(
- orders,
- ({ resultOrders, remainingFillAmount, ordersRemainingFillableMakerAssetAmounts }, order, index) => {
- if (remainingFillAmount.isLessThanOrEqualTo(constants.ZERO_AMOUNT)) {
- return {
- resultOrders,
- remainingFillAmount: constants.ZERO_AMOUNT,
- ordersRemainingFillableMakerAssetAmounts,
- };
- } else {
- const makerAssetAmountAvailable = remainingFillableMakerAssetAmounts[index];
- const shouldIncludeOrder = makerAssetAmountAvailable.gt(constants.ZERO_AMOUNT);
- // if there is no makerAssetAmountAvailable do not append order to resultOrders
- // if we have exceeded the total amount we want to fill set remainingFillAmount to 0
- return {
- resultOrders: shouldIncludeOrder ? _.concat(resultOrders, order) : resultOrders,
- ordersRemainingFillableMakerAssetAmounts: shouldIncludeOrder
- ? _.concat(ordersRemainingFillableMakerAssetAmounts, makerAssetAmountAvailable)
- : ordersRemainingFillableMakerAssetAmounts,
- remainingFillAmount: BigNumber.max(
- constants.ZERO_AMOUNT,
- remainingFillAmount.minus(makerAssetAmountAvailable),
- ),
- };
- }
- },
- {
- resultOrders: [] as T[],
- remainingFillAmount: totalFillAmount,
- ordersRemainingFillableMakerAssetAmounts: [] as BigNumber[],
- },
- );
- return result;
- },
- /**
- * Takes an array of orders and an array of feeOrders. Returns a subset of the feeOrders that has enough ZRX
- * in order to fill the takerFees required by orders plus a slippageBufferAmount.
- * Iterates from first feeOrder to last. Sort the feeOrders by ascending rate in order to get the subset of
- * feeOrders that will cost the least ETH.
- * @param orders An array of objects that extend the Order interface. All orders should specify ZRX as
- * the makerAsset and WETH as the takerAsset.
- * @param feeOrders An array of objects that extend the Order interface. All orders should specify ZRX as
- * the makerAsset and WETH as the takerAsset.
- * @param opts Optional arguments this function accepts.
- * @return Resulting orders and remaining fee amount that could not be covered by the input.
- */
- findFeeOrdersThatCoverFeesForTargetOrders<T extends Order>(
- orders: T[],
- feeOrders: T[],
- opts?: FindFeeOrdersThatCoverFeesForTargetOrdersOpts,
- ): FeeOrdersAndRemainingFeeAmount<T> {
- assert.doesConformToSchema('orders', orders, schemas.ordersSchema);
- assert.doesConformToSchema('feeOrders', feeOrders, schemas.ordersSchema);
- // try to get remainingFillableMakerAssetAmounts from opts, if it's not there, use makerAssetAmount values from orders
- const remainingFillableMakerAssetAmounts = _.get(
- opts,
- 'remainingFillableMakerAssetAmounts',
- _.map(orders, order => order.makerAssetAmount),
- ) as BigNumber[];
- _.forEach(remainingFillableMakerAssetAmounts, (amount, index) =>
- assert.isValidBaseUnitAmount(`remainingFillableMakerAssetAmount[${index}]`, amount),
- );
- assert.assert(
- orders.length === remainingFillableMakerAssetAmounts.length,
- 'Expected orders.length to equal opts.remainingFillableMakerAssetAmounts.length',
- );
- // try to get remainingFillableFeeAmounts from opts, if it's not there, use makerAssetAmount values from feeOrders
- const remainingFillableFeeAmounts = _.get(
- opts,
- 'remainingFillableFeeAmounts',
- _.map(feeOrders, order => order.makerAssetAmount),
- ) as BigNumber[];
- _.forEach(remainingFillableFeeAmounts, (amount, index) =>
- assert.isValidBaseUnitAmount(`remainingFillableFeeAmounts[${index}]`, amount),
- );
- assert.assert(
- feeOrders.length === remainingFillableFeeAmounts.length,
- 'Expected feeOrders.length to equal opts.remainingFillableFeeAmounts.length',
- );
- // try to get slippageBufferAmount from opts, if it's not there, default to 0
- const slippageBufferAmount = _.get(opts, 'slippageBufferAmount', constants.ZERO_AMOUNT) as BigNumber;
- assert.isValidBaseUnitAmount('opts.slippageBufferAmount', slippageBufferAmount);
- // calculate total amount of ZRX needed to fill orders
- const totalFeeAmount = _.reduce(
- orders,
- (accFees, order, index) => {
- const makerAssetAmountAvailable = remainingFillableMakerAssetAmounts[index];
- const feeToFillMakerAssetAmountAvailable = makerAssetAmountAvailable
- .multipliedBy(order.takerFee)
- .dividedToIntegerBy(order.makerAssetAmount);
- return accFees.plus(feeToFillMakerAssetAmountAvailable);
- },
- constants.ZERO_AMOUNT,
- );
- const {
- resultOrders,
- remainingFillAmount,
- ordersRemainingFillableMakerAssetAmounts,
- } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(feeOrders, totalFeeAmount, {
- remainingFillableMakerAssetAmounts: remainingFillableFeeAmounts,
- slippageBufferAmount,
- });
- return {
- resultFeeOrders: resultOrders,
- remainingFeeAmount: remainingFillAmount,
- feeOrdersRemainingFillableMakerAssetAmounts: ordersRemainingFillableMakerAssetAmounts,
- };
- // 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/src/order_factory.ts b/packages/order-utils/src/order_factory.ts
deleted file mode 100644
index f7b855bfb..000000000
--- a/packages/order-utils/src/order_factory.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import { Order, SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Provider } from 'ethereum-types';
-import * as _ from 'lodash';
-
-import { constants } from './constants';
-import { orderHashUtils } from './order_hash';
-import { generatePseudoRandomSalt } from './salt';
-import { signatureUtils } from './signature_utils';
-import { CreateOrderOpts } from './types';
-export const orderFactory = {
- createOrderFromPartial(partialOrder: Partial<Order>): Order {
- const defaultOrder = generateEmptyOrder();
- return {
- ...defaultOrder,
- ...partialOrder,
- };
- },
- createSignedOrderFromPartial(partialSignedOrder: Partial<SignedOrder>): SignedOrder {
- const defaultOrder = generateEmptySignedOrder();
- return {
- ...defaultOrder,
- ...partialSignedOrder,
- };
- },
- createOrder(
- makerAddress: string,
- makerAssetAmount: BigNumber,
- makerAssetData: string,
- takerAssetAmount: BigNumber,
- takerAssetData: string,
- exchangeAddress: string,
- createOrderOpts: CreateOrderOpts = generateDefaultCreateOrderOpts(),
- ): Order {
- const defaultCreateOrderOpts = generateDefaultCreateOrderOpts();
- const order = {
- makerAddress,
- makerAssetAmount,
- takerAssetAmount,
- makerAssetData,
- takerAssetData,
- exchangeAddress,
- takerAddress: createOrderOpts.takerAddress || defaultCreateOrderOpts.takerAddress,
- senderAddress: createOrderOpts.senderAddress || defaultCreateOrderOpts.senderAddress,
- makerFee: createOrderOpts.makerFee || defaultCreateOrderOpts.makerFee,
- takerFee: createOrderOpts.takerFee || defaultCreateOrderOpts.takerFee,
- feeRecipientAddress: createOrderOpts.feeRecipientAddress || defaultCreateOrderOpts.feeRecipientAddress,
- salt: createOrderOpts.salt || defaultCreateOrderOpts.salt,
- expirationTimeSeconds:
- createOrderOpts.expirationTimeSeconds || defaultCreateOrderOpts.expirationTimeSeconds,
- };
- return order;
- },
- async createSignedOrderAsync(
- provider: Provider,
- makerAddress: string,
- makerAssetAmount: BigNumber,
- makerAssetData: string,
- takerAssetAmount: BigNumber,
- takerAssetData: string,
- exchangeAddress: string,
- createOrderOpts?: CreateOrderOpts,
- ): Promise<SignedOrder> {
- const order = orderFactory.createOrder(
- makerAddress,
- makerAssetAmount,
- makerAssetData,
- takerAssetAmount,
- takerAssetData,
- exchangeAddress,
- createOrderOpts,
- );
- const orderHash = orderHashUtils.getOrderHashHex(order);
- const signature = await signatureUtils.ecSignHashAsync(provider, orderHash, makerAddress);
- const signedOrder: SignedOrder = _.assign(order, { signature });
- return signedOrder;
- },
-};
-
-function generateEmptySignedOrder(): SignedOrder {
- return {
- ...generateEmptyOrder(),
- signature: constants.NULL_BYTES,
- };
-}
-function generateEmptyOrder(): Order {
- return {
- senderAddress: constants.NULL_ADDRESS,
- makerAddress: constants.NULL_ADDRESS,
- takerAddress: constants.NULL_ADDRESS,
- makerFee: constants.ZERO_AMOUNT,
- takerFee: constants.ZERO_AMOUNT,
- makerAssetAmount: constants.ZERO_AMOUNT,
- takerAssetAmount: constants.ZERO_AMOUNT,
- makerAssetData: constants.NULL_BYTES,
- takerAssetData: constants.NULL_BYTES,
- salt: generatePseudoRandomSalt(),
- exchangeAddress: constants.NULL_ADDRESS,
- feeRecipientAddress: constants.NULL_ADDRESS,
- expirationTimeSeconds: constants.INFINITE_TIMESTAMP_SEC,
- };
-}
-
-function generateDefaultCreateOrderOpts(): {
- takerAddress: string;
- senderAddress: string;
- makerFee: BigNumber;
- takerFee: BigNumber;
- feeRecipientAddress: string;
- salt: BigNumber;
- expirationTimeSeconds: BigNumber;
-} {
- return {
- takerAddress: constants.NULL_ADDRESS,
- senderAddress: constants.NULL_ADDRESS,
- makerFee: constants.ZERO_AMOUNT,
- takerFee: constants.ZERO_AMOUNT,
- feeRecipientAddress: constants.NULL_ADDRESS,
- salt: generatePseudoRandomSalt(),
- expirationTimeSeconds: constants.INFINITE_TIMESTAMP_SEC,
- };
-}
diff --git a/packages/order-utils/src/order_hash.ts b/packages/order-utils/src/order_hash.ts
deleted file mode 100644
index c8e9be71e..000000000
--- a/packages/order-utils/src/order_hash.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { schemas, SchemaValidator } from '@0x/json-schemas';
-import { Order, SignedOrder } from '@0x/types';
-import { signTypedDataUtils } from '@0x/utils';
-import * as _ from 'lodash';
-
-import { assert } from './assert';
-import { eip712Utils } from './eip712_utils';
-
-const INVALID_TAKER_FORMAT = 'instance.takerAddress is not of a type(s) string';
-
-export const orderHashUtils = {
- /**
- * Checks if the supplied hex encoded order hash is valid.
- * Note: Valid means it has the expected format, not that an order with the orderHash exists.
- * Use this method when processing orderHashes submitted as user input.
- * @param orderHash Hex encoded orderHash.
- * @return Whether the supplied orderHash has the expected format.
- */
- isValidOrderHash(orderHash: string): boolean {
- // Since this method can be called to check if any arbitrary string conforms to an orderHash's
- // format, we only assert that we were indeed passed a string.
- assert.isString('orderHash', orderHash);
- const schemaValidator = new SchemaValidator();
- const isValid = schemaValidator.validate(orderHash, schemas.orderHashSchema).valid;
- return isValid;
- },
- /**
- * Computes the orderHash for a supplied order.
- * @param order An object that conforms to the Order or SignedOrder interface definitions.
- * @return Hex encoded string orderHash from hashing the supplied order.
- */
- getOrderHashHex(order: SignedOrder | Order): string {
- try {
- assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
- } catch (error) {
- if (_.includes(error.message, INVALID_TAKER_FORMAT)) {
- const errMsg =
- 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
- throw new Error(errMsg);
- }
- throw error;
- }
-
- const orderHashBuff = orderHashUtils.getOrderHashBuffer(order);
- const orderHashHex = `0x${orderHashBuff.toString('hex')}`;
- return orderHashHex;
- },
- /**
- * Computes the orderHash for a supplied order
- * @param order An object that conforms to the Order or SignedOrder interface definitions.
- * @return A Buffer containing the resulting orderHash from hashing the supplied order
- */
- getOrderHashBuffer(order: SignedOrder | Order): Buffer {
- const typedData = eip712Utils.createOrderTypedData(order);
- const orderHashBuff = signTypedDataUtils.generateTypedDataHash(typedData);
- return orderHashBuff;
- },
-};
diff --git a/packages/order-utils/src/order_state_utils.ts b/packages/order-utils/src/order_state_utils.ts
deleted file mode 100644
index 430178b5d..000000000
--- a/packages/order-utils/src/order_state_utils.ts
+++ /dev/null
@@ -1,346 +0,0 @@
-import {
- ExchangeContractErrs,
- ObjectMap,
- OrderRelevantState,
- OrderState,
- OrderStateInvalid,
- OrderStateValid,
- SignedOrder,
-} from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-
-import { AbstractBalanceAndProxyAllowanceFetcher } from './abstract/abstract_balance_and_proxy_allowance_fetcher';
-import { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_filled_cancelled_fetcher';
-import { assetDataUtils } from './asset_data_utils';
-import { orderHashUtils } from './order_hash';
-import { OrderValidationUtils } from './order_validation_utils';
-import { RemainingFillableCalculator } from './remaining_fillable_calculator';
-import { utils } from './utils';
-
-interface SidedOrderRelevantState {
- isMakerSide: boolean;
- traderBalance: BigNumber;
- traderIndividualBalances: ObjectMap<BigNumber>;
- traderProxyAllowance: BigNumber;
- traderIndividualProxyAllowances: ObjectMap<BigNumber>;
- traderFeeBalance: BigNumber;
- traderFeeProxyAllowance: BigNumber;
- filledTakerAssetAmount: BigNumber;
- remainingFillableAssetAmount: BigNumber;
- isOrderCancelled: boolean;
-}
-interface OrderValidResult {
- isValid: true;
-}
-interface OrderInvalidResult {
- isValid: false;
- error: ExchangeContractErrs;
-}
-type OrderValidationResult = OrderValidResult | OrderInvalidResult;
-
-export class OrderStateUtils {
- private readonly _balanceAndProxyAllowanceFetcher: AbstractBalanceAndProxyAllowanceFetcher;
- private readonly _orderFilledCancelledFetcher: AbstractOrderFilledCancelledFetcher;
- private static _validateIfOrderIsValid(
- signedOrder: SignedOrder,
- sidedOrderRelevantState: SidedOrderRelevantState,
- ): OrderValidationResult {
- const isMakerSide = sidedOrderRelevantState.isMakerSide;
- if (sidedOrderRelevantState.isOrderCancelled) {
- return { isValid: false, error: ExchangeContractErrs.OrderCancelled };
- }
- const availableTakerAssetAmount = signedOrder.takerAssetAmount.minus(
- sidedOrderRelevantState.filledTakerAssetAmount,
- );
- if (availableTakerAssetAmount.eq(0)) {
- return { isValid: false, error: ExchangeContractErrs.OrderRemainingFillAmountZero };
- }
-
- if (sidedOrderRelevantState.traderBalance.eq(0)) {
- const error = isMakerSide
- ? ExchangeContractErrs.InsufficientMakerBalance
- : ExchangeContractErrs.InsufficientTakerBalance;
- return { isValid: false, error };
- }
- if (sidedOrderRelevantState.traderProxyAllowance.eq(0)) {
- const error = isMakerSide
- ? ExchangeContractErrs.InsufficientMakerAllowance
- : ExchangeContractErrs.InsufficientTakerAllowance;
- return { isValid: false, error };
- }
- if (!signedOrder.makerFee.eq(0)) {
- if (sidedOrderRelevantState.traderFeeBalance.eq(0)) {
- const error = isMakerSide
- ? ExchangeContractErrs.InsufficientMakerFeeBalance
- : ExchangeContractErrs.InsufficientTakerFeeBalance;
- return { isValid: false, error };
- }
- if (sidedOrderRelevantState.traderFeeProxyAllowance.eq(0)) {
- const error = isMakerSide
- ? ExchangeContractErrs.InsufficientMakerFeeAllowance
- : ExchangeContractErrs.InsufficientTakerFeeAllowance;
- return { isValid: false, error };
- }
- }
- const remainingTakerAssetAmount = signedOrder.takerAssetAmount.minus(
- sidedOrderRelevantState.filledTakerAssetAmount,
- );
- const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(
- remainingTakerAssetAmount,
- signedOrder.takerAssetAmount,
- signedOrder.makerAssetAmount,
- );
- if (isRoundingError) {
- return { isValid: false, error: ExchangeContractErrs.OrderFillRoundingError };
- }
- return { isValid: true };
- }
- /**
- * Instantiate OrderStateUtils
- * @param balanceAndProxyAllowanceFetcher A class that is capable of fetching balances
- * and proxyAllowances for Ethereum addresses. It must implement AbstractBalanceAndProxyAllowanceFetcher
- * @param orderFilledCancelledFetcher A class that is capable of fetching whether an order
- * is cancelled and how much of it has been filled. It must implement AbstractOrderFilledCancelledFetcher
- * @return Instance of OrderStateUtils
- */
- constructor(
- balanceAndProxyAllowanceFetcher: AbstractBalanceAndProxyAllowanceFetcher,
- orderFilledCancelledFetcher: AbstractOrderFilledCancelledFetcher,
- ) {
- this._balanceAndProxyAllowanceFetcher = balanceAndProxyAllowanceFetcher;
- this._orderFilledCancelledFetcher = orderFilledCancelledFetcher;
- }
- /**
- * Get the orderState for an "open" order (i.e where takerAddress=NULL_ADDRESS)
- * This method will only check the maker's balance/allowance to calculate the
- * OrderState.
- * @param signedOrder The order of interest
- * @return State relevant to the signedOrder, as well as whether the signedOrder is "valid".
- * Validity is defined as a non-zero amount of the order can still be filled.
- */
- public async getOpenOrderStateAsync(signedOrder: SignedOrder, transactionHash?: string): Promise<OrderState> {
- const orderRelevantState = await this.getOpenOrderRelevantStateAsync(signedOrder);
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- const isOrderCancelled = await this._orderFilledCancelledFetcher.isOrderCancelledAsync(signedOrder);
- const sidedOrderRelevantState = {
- isMakerSide: true,
- traderBalance: orderRelevantState.makerBalance,
- traderIndividualBalances: orderRelevantState.makerIndividualBalances,
- traderProxyAllowance: orderRelevantState.makerProxyAllowance,
- traderIndividualProxyAllowances: orderRelevantState.makerIndividualProxyAllowances,
- traderFeeBalance: orderRelevantState.makerFeeBalance,
- traderFeeProxyAllowance: orderRelevantState.makerFeeProxyAllowance,
- filledTakerAssetAmount: orderRelevantState.filledTakerAssetAmount,
- remainingFillableAssetAmount: orderRelevantState.remainingFillableMakerAssetAmount,
- isOrderCancelled,
- };
- const orderValidationResult = OrderStateUtils._validateIfOrderIsValid(signedOrder, sidedOrderRelevantState);
- if (orderValidationResult.isValid) {
- const orderState: OrderStateValid = {
- isValid: true,
- orderHash,
- orderRelevantState,
- transactionHash,
- };
- return orderState;
- } else {
- const orderState: OrderStateInvalid = {
- isValid: false,
- orderHash,
- error: orderValidationResult.error,
- transactionHash,
- };
- return orderState;
- }
- }
- /**
- * Get state relevant to an order (i.e makerBalance, makerAllowance, filledTakerAssetAmount, etc...
- * @param signedOrder Order of interest
- * @return An instance of OrderRelevantState
- */
- public async getOpenOrderRelevantStateAsync(signedOrder: SignedOrder): Promise<OrderRelevantState> {
- const isMaker = true;
- const sidedOrderRelevantState = await this._getSidedOrderRelevantStateAsync(
- isMaker,
- signedOrder,
- signedOrder.takerAddress,
- );
- const remainingFillableTakerAssetAmount = sidedOrderRelevantState.remainingFillableAssetAmount
- .times(signedOrder.takerAssetAmount)
- .dividedToIntegerBy(signedOrder.makerAssetAmount);
-
- const orderRelevantState = {
- makerBalance: sidedOrderRelevantState.traderBalance,
- makerIndividualBalances: sidedOrderRelevantState.traderIndividualBalances,
- makerProxyAllowance: sidedOrderRelevantState.traderProxyAllowance,
- makerIndividualProxyAllowances: sidedOrderRelevantState.traderIndividualProxyAllowances,
- makerFeeBalance: sidedOrderRelevantState.traderFeeBalance,
- makerFeeProxyAllowance: sidedOrderRelevantState.traderFeeProxyAllowance,
- filledTakerAssetAmount: sidedOrderRelevantState.filledTakerAssetAmount,
- remainingFillableMakerAssetAmount: sidedOrderRelevantState.remainingFillableAssetAmount,
- remainingFillableTakerAssetAmount,
- };
- return orderRelevantState;
- }
- /**
- * Get the max amount of the supplied order's takerAmount that could still be filled
- * @param signedOrder Order of interest
- * @param takerAddress Hypothetical taker of the order
- * @return fillableTakerAssetAmount
- */
- public async getMaxFillableTakerAssetAmountAsync(
- signedOrder: SignedOrder,
- takerAddress: string,
- ): Promise<BigNumber> {
- // Get max fillable amount for an order, considering the makers ability to fill
- let isMaker = true;
- const orderRelevantMakerState = await this._getSidedOrderRelevantStateAsync(
- isMaker,
- signedOrder,
- signedOrder.takerAddress,
- );
- const remainingFillableTakerAssetAmountGivenMakersStatus = signedOrder.makerAssetAmount.eq(0)
- ? new BigNumber(0)
- : utils.getPartialAmountFloor(
- orderRelevantMakerState.remainingFillableAssetAmount,
- signedOrder.makerAssetAmount,
- signedOrder.takerAssetAmount,
- );
-
- // Get max fillable amount for an order, considering the takers ability to fill
- isMaker = false;
- const orderRelevantTakerState = await this._getSidedOrderRelevantStateAsync(isMaker, signedOrder, takerAddress);
- const remainingFillableTakerAssetAmountGivenTakersStatus = orderRelevantTakerState.remainingFillableAssetAmount;
-
- // The min of these two in the actualy max fillable by either party
- const fillableTakerAssetAmount = BigNumber.min(
- remainingFillableTakerAssetAmountGivenMakersStatus,
- remainingFillableTakerAssetAmountGivenTakersStatus,
- );
-
- return fillableTakerAssetAmount;
- }
- private async _getSidedOrderRelevantStateAsync(
- isMakerSide: boolean,
- signedOrder: SignedOrder,
- takerAddress: string,
- ): Promise<SidedOrderRelevantState> {
- let traderAddress;
- let assetData;
- let assetAmount;
- let feeAmount;
- if (isMakerSide) {
- traderAddress = signedOrder.makerAddress;
- assetData = signedOrder.makerAssetData;
- assetAmount = signedOrder.makerAssetAmount;
- feeAmount = signedOrder.makerFee;
- } else {
- traderAddress = takerAddress;
- assetData = signedOrder.takerAssetData;
- assetAmount = signedOrder.takerAssetAmount;
- feeAmount = signedOrder.takerFee;
- }
- const zrxAssetData = this._orderFilledCancelledFetcher.getZRXAssetData();
- const isAssetZRX = assetData === zrxAssetData;
-
- const traderBalance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(assetData, traderAddress);
- const traderIndividualBalances = await this._getAssetBalancesAsync(assetData, traderAddress);
- const traderProxyAllowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync(
- assetData,
- traderAddress,
- );
- const traderIndividualProxyAllowances = await this._getAssetProxyAllowancesAsync(assetData, traderAddress);
- const traderFeeBalance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(
- zrxAssetData,
- traderAddress,
- );
- const traderFeeProxyAllowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync(
- zrxAssetData,
- traderAddress,
- );
-
- const transferrableTraderAssetAmount = BigNumber.min(traderProxyAllowance, traderBalance);
- const transferrableFeeAssetAmount = BigNumber.min(traderFeeProxyAllowance, traderFeeBalance);
-
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- const filledTakerAssetAmount = await this._orderFilledCancelledFetcher.getFilledTakerAmountAsync(orderHash);
- const totalMakerAssetAmount = signedOrder.makerAssetAmount;
- const totalTakerAssetAmount = signedOrder.takerAssetAmount;
- const isOrderCancelled = await this._orderFilledCancelledFetcher.isOrderCancelledAsync(signedOrder);
- const remainingTakerAssetAmount = isOrderCancelled
- ? new BigNumber(0)
- : totalTakerAssetAmount.minus(filledTakerAssetAmount);
- const remainingMakerAssetAmount = remainingTakerAssetAmount.eq(0)
- ? new BigNumber(0)
- : remainingTakerAssetAmount.times(totalMakerAssetAmount).dividedToIntegerBy(totalTakerAssetAmount);
- const remainingAssetAmount = isMakerSide ? remainingMakerAssetAmount : remainingTakerAssetAmount;
-
- const remainingFillableCalculator = new RemainingFillableCalculator(
- feeAmount,
- assetAmount,
- isAssetZRX,
- transferrableTraderAssetAmount,
- transferrableFeeAssetAmount,
- remainingAssetAmount,
- );
- const remainingFillableAssetAmount = remainingFillableCalculator.computeRemainingFillable();
-
- const sidedOrderRelevantState = {
- isMakerSide,
- traderBalance,
- traderIndividualBalances,
- traderProxyAllowance,
- traderIndividualProxyAllowances,
- traderFeeBalance,
- traderFeeProxyAllowance,
- filledTakerAssetAmount,
- remainingFillableAssetAmount,
- isOrderCancelled,
- };
- return sidedOrderRelevantState;
- }
- private async _getAssetBalancesAsync(
- assetData: string,
- traderAddress: string,
- initialBalances: ObjectMap<BigNumber> = {},
- ): Promise<ObjectMap<BigNumber>> {
- const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData);
- let balances: ObjectMap<BigNumber> = { ...initialBalances };
- if (assetDataUtils.isERC20AssetData(decodedAssetData) || assetDataUtils.isERC721AssetData(decodedAssetData)) {
- const balance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(assetData, traderAddress);
- const tokenAddress = decodedAssetData.tokenAddress;
- balances[tokenAddress] = _.isUndefined(initialBalances[tokenAddress])
- ? balance
- : balances[tokenAddress].plus(balance);
- } else if (assetDataUtils.isMultiAssetData(decodedAssetData)) {
- for (const assetDataElement of decodedAssetData.nestedAssetData) {
- balances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, balances);
- }
- }
- return balances;
- }
- private async _getAssetProxyAllowancesAsync(
- assetData: string,
- traderAddress: string,
- initialAllowances: ObjectMap<BigNumber> = {},
- ): Promise<ObjectMap<BigNumber>> {
- const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData);
- let allowances: ObjectMap<BigNumber> = { ...initialAllowances };
- if (assetDataUtils.isERC20AssetData(decodedAssetData) || assetDataUtils.isERC721AssetData(decodedAssetData)) {
- const allowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync(
- assetData,
- traderAddress,
- );
- const tokenAddress = decodedAssetData.tokenAddress;
- allowances[tokenAddress] = _.isUndefined(initialAllowances[tokenAddress])
- ? allowance
- : allowances[tokenAddress].plus(allowance);
- } else if (assetDataUtils.isMultiAssetData(decodedAssetData)) {
- for (const assetDataElement of decodedAssetData.nestedAssetData) {
- allowances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, allowances);
- }
- }
- return allowances;
- }
-}
diff --git a/packages/order-utils/src/order_validation_utils.ts b/packages/order-utils/src/order_validation_utils.ts
deleted file mode 100644
index 95215d918..000000000
--- a/packages/order-utils/src/order_validation_utils.ts
+++ /dev/null
@@ -1,257 +0,0 @@
-import { ExchangeContractErrs, RevertReason, SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Provider } from 'ethereum-types';
-import * as _ from 'lodash';
-
-import { OrderError, TradeSide, TransferType } from './types';
-
-import { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_filled_cancelled_fetcher';
-import { constants } from './constants';
-import { ExchangeTransferSimulator } from './exchange_transfer_simulator';
-import { orderHashUtils } from './order_hash';
-import { signatureUtils } from './signature_utils';
-import { utils } from './utils';
-
-/**
- * A utility class for validating orders
- */
-export class OrderValidationUtils {
- private readonly _orderFilledCancelledFetcher: AbstractOrderFilledCancelledFetcher;
- private readonly _provider: Provider;
- /**
- * 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)) {
- throw new Error('denominator cannot be 0');
- }
- const remainder = target.multipliedBy(numerator).mod(denominator);
- if (remainder.eq(0)) {
- return false; // no rounding error
- }
-
- // tslint:disable-next-line:custom-no-magic-numbers
- const errPercentageTimes1000000 = remainder.multipliedBy(1000000).div(numerator.multipliedBy(target));
- // tslint:disable-next-line:custom-no-magic-numbers
- 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,
- fillTakerAssetAmount: BigNumber,
- senderAddress: string,
- zrxAssetData: string,
- ): Promise<void> {
- const fillMakerTokenAmount = utils.getPartialAmountFloor(
- fillTakerAssetAmount,
- signedOrder.takerAssetAmount,
- signedOrder.makerAssetAmount,
- );
- await exchangeTradeEmulator.transferFromAsync(
- signedOrder.makerAssetData,
- signedOrder.makerAddress,
- senderAddress,
- fillMakerTokenAmount,
- TradeSide.Maker,
- TransferType.Trade,
- );
- await exchangeTradeEmulator.transferFromAsync(
- signedOrder.takerAssetData,
- senderAddress,
- signedOrder.makerAddress,
- fillTakerAssetAmount,
- TradeSide.Taker,
- TransferType.Trade,
- );
- const makerFeeAmount = utils.getPartialAmountFloor(
- fillTakerAssetAmount,
- signedOrder.takerAssetAmount,
- signedOrder.makerFee,
- );
- await exchangeTradeEmulator.transferFromAsync(
- zrxAssetData,
- signedOrder.makerAddress,
- signedOrder.feeRecipientAddress,
- makerFeeAmount,
- TradeSide.Maker,
- TransferType.Fee,
- );
- const takerFeeAmount = utils.getPartialAmountFloor(
- fillTakerAssetAmount,
- signedOrder.takerAssetAmount,
- signedOrder.takerFee,
- );
- await exchangeTradeEmulator.transferFromAsync(
- zrxAssetData,
- senderAddress,
- signedOrder.feeRecipientAddress,
- takerFeeAmount,
- TradeSide.Taker,
- TransferType.Fee,
- );
- }
- private static _validateOrderNotExpiredOrThrow(expirationTimeSeconds: BigNumber): void {
- const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
- if (expirationTimeSeconds.isLessThan(currentUnixTimestampSec)) {
- throw new Error(RevertReason.OrderUnfillable);
- }
- }
- /**
- * Instantiate OrderValidationUtils
- * @param orderFilledCancelledFetcher A module that implements the AbstractOrderFilledCancelledFetcher
- * @return An instance of OrderValidationUtils
- */
- constructor(orderFilledCancelledFetcher: AbstractOrderFilledCancelledFetcher, provider: Provider) {
- this._orderFilledCancelledFetcher = orderFilledCancelledFetcher;
- this._provider = provider;
- }
- // TODO(fabio): remove this method once the smart contracts have been refactored
- // to return helpful revert reasons instead of ORDER_UNFILLABLE. Instruct devs
- // to make "calls" to validate order fillability + getOrderInfo for fillable amount.
- /**
- * 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,
- zrxAssetData: string,
- expectedFillTakerTokenAmount?: BigNumber,
- ): Promise<void> {
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- const isValidSignature = await signatureUtils.isValidSignatureAsync(
- this._provider,
- orderHash,
- signedOrder.signature,
- signedOrder.makerAddress,
- );
- if (!isValidSignature) {
- throw new Error(RevertReason.InvalidOrderSignature);
- }
-
- const isCancelled = await this._orderFilledCancelledFetcher.isOrderCancelledAsync(signedOrder);
- if (isCancelled) {
- throw new Error('CANCELLED');
- }
- const filledTakerTokenAmount = await this._orderFilledCancelledFetcher.getFilledTakerAmountAsync(orderHash);
- if (signedOrder.takerAssetAmount.eq(filledTakerTokenAmount)) {
- throw new Error('FULLY_FILLED');
- }
- try {
- OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationTimeSeconds);
- } catch (err) {
- throw new Error('EXPIRED');
- }
- let fillTakerAssetAmount = signedOrder.takerAssetAmount.minus(filledTakerTokenAmount);
- if (!_.isUndefined(expectedFillTakerTokenAmount)) {
- fillTakerAssetAmount = expectedFillTakerTokenAmount;
- }
- await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTradeEmulator,
- signedOrder,
- fillTakerAssetAmount,
- signedOrder.takerAddress,
- 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,
- signedOrder: SignedOrder,
- fillTakerAssetAmount: BigNumber,
- takerAddress: string,
- zrxAssetData: string,
- ): Promise<BigNumber> {
- if (signedOrder.makerAssetAmount.eq(0) || signedOrder.takerAssetAmount.eq(0)) {
- throw new Error(RevertReason.OrderUnfillable);
- }
- if (fillTakerAssetAmount.eq(0)) {
- throw new Error(RevertReason.InvalidTakerAmount);
- }
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- const isValid = await signatureUtils.isValidSignatureAsync(
- provider,
- orderHash,
- signedOrder.signature,
- signedOrder.makerAddress,
- );
- if (!isValid) {
- throw new Error(OrderError.InvalidSignature);
- }
- const filledTakerTokenAmount = await this._orderFilledCancelledFetcher.getFilledTakerAmountAsync(orderHash);
- if (signedOrder.takerAssetAmount.eq(filledTakerTokenAmount)) {
- throw new Error(RevertReason.OrderUnfillable);
- }
- if (signedOrder.takerAddress !== constants.NULL_ADDRESS && signedOrder.takerAddress !== takerAddress) {
- throw new Error(RevertReason.InvalidTaker);
- }
- OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationTimeSeconds);
- const remainingTakerTokenAmount = signedOrder.takerAssetAmount.minus(filledTakerTokenAmount);
- const desiredFillTakerTokenAmount = remainingTakerTokenAmount.isLessThan(fillTakerAssetAmount)
- ? remainingTakerTokenAmount
- : fillTakerAssetAmount;
- try {
- await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTradeEmulator,
- signedOrder,
- desiredFillTakerTokenAmount,
- takerAddress,
- zrxAssetData,
- );
- } catch (err) {
- const transferFailedErrorMessages = [
- ExchangeContractErrs.InsufficientMakerBalance,
- ExchangeContractErrs.InsufficientMakerFeeBalance,
- ExchangeContractErrs.InsufficientTakerBalance,
- ExchangeContractErrs.InsufficientTakerFeeBalance,
- ExchangeContractErrs.InsufficientMakerAllowance,
- ExchangeContractErrs.InsufficientMakerFeeAllowance,
- ExchangeContractErrs.InsufficientTakerAllowance,
- ExchangeContractErrs.InsufficientTakerFeeAllowance,
- ];
- if (_.includes(transferFailedErrorMessages, err.message)) {
- throw new Error(RevertReason.TransferFailed);
- }
- throw err;
- }
-
- const wouldRoundingErrorOccur = OrderValidationUtils.isRoundingErrorFloor(
- desiredFillTakerTokenAmount,
- signedOrder.takerAssetAmount,
- signedOrder.makerAssetAmount,
- );
- if (wouldRoundingErrorOccur) {
- throw new Error(RevertReason.RoundingError);
- }
- return filledTakerTokenAmount;
- }
-}
diff --git a/packages/order-utils/src/parsing_utils.ts b/packages/order-utils/src/parsing_utils.ts
deleted file mode 100644
index 98c6899fe..000000000
--- a/packages/order-utils/src/parsing_utils.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-
-export const orderParsingUtils = {
- convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
- const result = _.assign({}, obj);
- _.each(fields, field => {
- _.update(result, field, (value: string) => {
- if (_.isUndefined(value)) {
- throw new Error(`Could not find field '${field}' while converting string fields to BigNumber.`);
- }
- return new BigNumber(value);
- });
- });
- return result;
- },
- convertOrderStringFieldsToBigNumber(order: any): any {
- return orderParsingUtils.convertStringsFieldsToBigNumbers(order, [
- 'makerAssetAmount',
- 'takerAssetAmount',
- 'makerFee',
- 'takerFee',
- 'expirationTimeSeconds',
- 'salt',
- ]);
- },
-};
diff --git a/packages/order-utils/src/rate_utils.ts b/packages/order-utils/src/rate_utils.ts
deleted file mode 100644
index dacdbd5a2..000000000
--- a/packages/order-utils/src/rate_utils.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { schemas } from '@0x/json-schemas';
-import { Order } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-
-import { assert } from './assert';
-import { constants } from './constants';
-
-export const rateUtils = {
- /**
- * Takes an order and calculates the fee adjusted rate (takerAsset/makerAsset) by calculating how much takerAsset
- * is required to cover the fees (feeRate * takerFee), adding the takerAssetAmount and dividing by makerAssetAmount
- * @param order An object that conforms to the order interface
- * @param feeRate The market rate of ZRX denominated in takerAssetAmount
- * (ex. feeRate is 0.1 takerAsset/ZRX if it takes 1 unit of takerAsset to buy 10 ZRX)
- * Defaults to 0
- * @return The rate (takerAsset/makerAsset) of the order adjusted for fees
- */
- getFeeAdjustedRateOfOrder(order: Order, feeRate: BigNumber = constants.ZERO_AMOUNT): BigNumber {
- assert.doesConformToSchema('order', order, schemas.orderSchema);
- assert.isBigNumber('feeRate', feeRate);
- assert.assert(
- feeRate.gte(constants.ZERO_AMOUNT),
- `Expected feeRate: ${feeRate} to be greater than or equal to 0`,
- );
- const takerAssetAmountNeededToPayForFees = order.takerFee.multipliedBy(feeRate);
- const totalTakerAssetAmount = takerAssetAmountNeededToPayForFees.plus(order.takerAssetAmount);
- const rate = totalTakerAssetAmount.div(order.makerAssetAmount);
- return rate;
- },
- /**
- * Takes a fee order (makerAssetData corresponds to ZRX and takerAssetData corresponds to WETH) and calculates
- * the fee adjusted rate (WETH/ZRX) by dividing the takerAssetAmount by the makerAmount minus the takerFee
- * @param feeOrder An object that conforms to the order interface
- * @return The rate (WETH/ZRX) of the fee order adjusted for fees
- */
- getFeeAdjustedRateOfFeeOrder(feeOrder: Order): BigNumber {
- assert.doesConformToSchema('feeOrder', feeOrder, schemas.orderSchema);
- const zrxAmountAfterFees = feeOrder.makerAssetAmount.minus(feeOrder.takerFee);
- assert.assert(
- zrxAmountAfterFees.isGreaterThan(constants.ZERO_AMOUNT),
- `Expected takerFee: ${JSON.stringify(feeOrder.takerFee)} to be less than makerAssetAmount: ${JSON.stringify(
- feeOrder.makerAssetAmount,
- )}`,
- );
- const rate = feeOrder.takerAssetAmount.div(zrxAmountAfterFees);
- return rate;
- },
-};
diff --git a/packages/order-utils/src/remaining_fillable_calculator.ts b/packages/order-utils/src/remaining_fillable_calculator.ts
deleted file mode 100644
index 92ffc8e80..000000000
--- a/packages/order-utils/src/remaining_fillable_calculator.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { BigNumber } from '@0x/utils';
-
-export class RemainingFillableCalculator {
- private readonly _isTraderAssetZRX: boolean;
- // Transferrable Amount is the minimum of Approval and Balance
- private readonly _transferrableAssetAmount: BigNumber;
- private readonly _transferrableFeeAmount: BigNumber;
- private readonly _remainingOrderAssetAmount: BigNumber;
- private readonly _remainingOrderFeeAmount: BigNumber;
- private readonly _orderFee: BigNumber;
- private readonly _orderAssetAmount: BigNumber;
- constructor(
- orderFee: BigNumber,
- orderAssetAmount: BigNumber,
- isTraderAssetZRX: boolean,
- transferrableAssetAmount: BigNumber,
- transferrableFeeAmount: BigNumber,
- remainingOrderAssetAmount: BigNumber,
- ) {
- this._orderFee = orderFee;
- this._orderAssetAmount = orderAssetAmount;
- this._isTraderAssetZRX = isTraderAssetZRX;
- this._transferrableAssetAmount = transferrableAssetAmount;
- this._transferrableFeeAmount = transferrableFeeAmount;
- this._remainingOrderAssetAmount = remainingOrderAssetAmount;
- this._remainingOrderFeeAmount = orderAssetAmount.eq(0)
- ? new BigNumber(0)
- : remainingOrderAssetAmount.times(orderFee).dividedToIntegerBy(orderAssetAmount);
- }
- public computeRemainingFillable(): BigNumber {
- if (this._hasSufficientFundsForFeeAndTransferAmount()) {
- return this._remainingOrderAssetAmount;
- }
- if (this._orderFee.isZero()) {
- return BigNumber.min(this._remainingOrderAssetAmount, this._transferrableAssetAmount);
- }
- return this._calculatePartiallyFillableAssetAmount();
- }
- private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
- if (this._isTraderAssetZRX) {
- const totalZRXTransferAmountRequired = this._remainingOrderAssetAmount.plus(this._remainingOrderFeeAmount);
- const hasSufficientFunds = this._transferrableAssetAmount.isGreaterThanOrEqualTo(
- totalZRXTransferAmountRequired,
- );
- return hasSufficientFunds;
- } else {
- const hasSufficientFundsForTransferAmount = this._transferrableAssetAmount.isGreaterThanOrEqualTo(
- this._remainingOrderAssetAmount,
- );
- const hasSufficientFundsForFeeAmount = this._transferrableFeeAmount.isGreaterThanOrEqualTo(
- this._remainingOrderFeeAmount,
- );
- const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
- return hasSufficientFunds;
- }
- }
- private _calculatePartiallyFillableAssetAmount(): BigNumber {
- // Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1
- const orderToFeeRatio = this._orderAssetAmount.dividedBy(this._orderFee);
- // The number of times the trader (maker or taker) can fill the order, if each fill only required the transfer of a single
- // baseUnit of fee tokens.
- // Given 2 ZRXwei, the maximum amount of times trader can fill this order, in terms of fees, is 2
- const fillableTimesInFeeBaseUnits = BigNumber.min(this._transferrableFeeAmount, this._remainingOrderFeeAmount);
- // The number of times the trader can fill the order, given the traders asset Balance
- // Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, trader can fill this order 1 time.
- let fillableTimesInAssetUnits = this._transferrableAssetAmount.dividedBy(orderToFeeRatio);
- if (this._isTraderAssetZRX) {
- // If ZRX is the trader asset, the Fee and the trader fill amount need to be removed from the same pool;
- // 200 ZRXwei for 2ZRXwei fee can only be filled once (need 202 ZRXwei)
- const totalZRXTokenPooled = this._transferrableAssetAmount;
- // The purchasing power here is less as the tokens are taken from the same Pool
- // For every one number of fills, we have to take an extra ZRX out of the pool
- fillableTimesInAssetUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1)));
- }
- // When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
- // This can result in a RoundingError being thrown by the Exchange Contract.
- const partiallyFillableAssetAmount = fillableTimesInAssetUnits
- .times(this._orderAssetAmount)
- .dividedToIntegerBy(this._orderFee);
- const partiallyFillableFeeAmount = fillableTimesInFeeBaseUnits
- .times(this._orderAssetAmount)
- .dividedToIntegerBy(this._orderFee);
- const partiallyFillableAmount = BigNumber.min(partiallyFillableAssetAmount, partiallyFillableFeeAmount);
- return partiallyFillableAmount;
- }
-}
diff --git a/packages/order-utils/src/salt.ts b/packages/order-utils/src/salt.ts
deleted file mode 100644
index 95df66c99..000000000
--- a/packages/order-utils/src/salt.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { BigNumber } from '@0x/utils';
-
-const MAX_DIGITS_IN_UNSIGNED_256_INT = 78;
-
-/**
- * Generates a pseudo-random 256-bit salt.
- * The salt can be included in a 0x order, ensuring that the order generates a unique orderHash
- * and will not collide with other outstanding orders that are identical in all other parameters.
- * @return A pseudo-random 256-bit number that can be used as a salt.
- */
-export function generatePseudoRandomSalt(): BigNumber {
- // BigNumber.random returns a pseudo-random number between 0 & 1 with a passed in number of decimal places.
- // Source: https://mikemcl.github.io/bignumber.js/#random
- const randomNumber = BigNumber.random(MAX_DIGITS_IN_UNSIGNED_256_INT);
- const factor = new BigNumber(10).pow(MAX_DIGITS_IN_UNSIGNED_256_INT - 1);
- const salt = randomNumber.times(factor).integerValue();
- return salt;
-}
diff --git a/packages/order-utils/src/signature_utils.ts b/packages/order-utils/src/signature_utils.ts
deleted file mode 100644
index 131144d48..000000000
--- a/packages/order-utils/src/signature_utils.ts
+++ /dev/null
@@ -1,417 +0,0 @@
-import { ExchangeContract, IValidatorContract, IWalletContract } from '@0x/abi-gen-wrappers';
-import * as artifacts from '@0x/contract-artifacts';
-import { schemas } from '@0x/json-schemas';
-import { ECSignature, Order, SignatureType, SignedOrder, ValidatorSignature } from '@0x/types';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import { Provider } from 'ethereum-types';
-import * as ethUtil from 'ethereumjs-util';
-import * as _ from 'lodash';
-
-import { assert } from './assert';
-import { eip712Utils } from './eip712_utils';
-import { orderHashUtils } from './order_hash';
-import { OrderError } from './types';
-import { utils } from './utils';
-
-export const signatureUtils = {
- /**
- * Verifies that the provided signature is valid according to the 0x Protocol smart contracts
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature A hex encoded 0x Protocol signature made up of: [TypeSpecificData][SignatureType].
- * E.g [vrs][SignatureType.EIP712]
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the signature is valid for the supplied signerAddress and data.
- */
- async isValidSignatureAsync(
- provider: Provider,
- data: string,
- signature: string,
- signerAddress: string,
- ): Promise<boolean> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('data', data);
- assert.isHexString('signature', signature);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const signatureTypeIndexIfExists = utils.getSignatureTypeIndexIfExists(signature);
- if (_.isUndefined(signatureTypeIndexIfExists)) {
- throw new Error(`Unrecognized signatureType in signature: ${signature}`);
- }
-
- switch (signatureTypeIndexIfExists) {
- case SignatureType.Illegal:
- case SignatureType.Invalid:
- return false;
-
- case SignatureType.EIP712: {
- const ecSignature = signatureUtils.parseECSignature(signature);
- return signatureUtils.isValidECSignature(data, ecSignature, signerAddress);
- }
-
- case SignatureType.EthSign: {
- const ecSignature = signatureUtils.parseECSignature(signature);
- const prefixedMessageHex = signatureUtils.addSignedMessagePrefix(data);
- return signatureUtils.isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
- }
-
- case SignatureType.Wallet: {
- const isValid = await signatureUtils.isValidWalletSignatureAsync(
- provider,
- data,
- signature,
- signerAddress,
- );
- return isValid;
- }
-
- case SignatureType.Validator: {
- const isValid = await signatureUtils.isValidValidatorSignatureAsync(
- provider,
- data,
- signature,
- signerAddress,
- );
- return isValid;
- }
-
- case SignatureType.PreSigned: {
- return signatureUtils.isValidPresignedSignatureAsync(provider, data, signerAddress);
- }
-
- default:
- throw new Error(`Unhandled SignatureType: ${signatureTypeIndexIfExists}`);
- }
- },
- /**
- * Verifies that the provided presigned signature is valid according to the 0x Protocol smart contracts
- * @param provider Web3 provider to use for all JSON RPC requests
- * @param data The hex encoded data signed by the supplied signature
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the data was preSigned by the supplied signerAddress
- */
- async isValidPresignedSignatureAsync(provider: Provider, data: string, signerAddress: string): Promise<boolean> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('data', data);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const exchangeContract = new ExchangeContract(artifacts.Exchange.compilerOutput.abi, signerAddress, provider);
- const isValid = await exchangeContract.preSigned.callAsync(data, signerAddress);
- return isValid;
- },
- /**
- * Verifies that the provided wallet signature is valid according to the 0x Protocol smart contracts
- * @param provider Web3 provider to use for all JSON RPC requests
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the data was preSigned by the supplied signerAddress.
- */
- async isValidWalletSignatureAsync(
- provider: Provider,
- data: string,
- signature: string,
- signerAddress: string,
- ): Promise<boolean> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('data', data);
- assert.isHexString('signature', signature);
- assert.isETHAddressHex('signerAddress', signerAddress);
- // tslint:disable-next-line:custom-no-magic-numbers
- const signatureWithoutType = signature.slice(0, -2);
- const walletContract = new IWalletContract(artifacts.IWallet.compilerOutput.abi, signerAddress, provider);
- const isValid = await walletContract.isValidSignature.callAsync(data, signatureWithoutType);
- return isValid;
- },
- /**
- * Verifies that the provided validator signature is valid according to the 0x Protocol smart contracts
- * @param provider Web3 provider to use for all JSON RPC requests
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the data was preSigned by the supplied signerAddress.
- */
- async isValidValidatorSignatureAsync(
- provider: Provider,
- data: string,
- signature: string,
- signerAddress: string,
- ): Promise<boolean> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('data', data);
- assert.isHexString('signature', signature);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const validatorSignature = parseValidatorSignature(signature);
- const exchangeContract = new ExchangeContract(artifacts.Exchange.compilerOutput.abi, signerAddress, provider);
- const isValidatorApproved = await exchangeContract.allowedValidators.callAsync(
- signerAddress,
- validatorSignature.validatorAddress,
- );
- if (!isValidatorApproved) {
- throw new Error(
- `Validator ${validatorSignature.validatorAddress} was not pre-approved by ${signerAddress}.`,
- );
- }
-
- const validatorContract = new IValidatorContract(
- artifacts.IValidator.compilerOutput.abi,
- signerAddress,
- provider,
- );
- const isValid = await validatorContract.isValidSignature.callAsync(
- data,
- signerAddress,
- validatorSignature.signature,
- );
- return isValid;
- },
- /**
- * Checks if the supplied elliptic curve signature corresponds to signing `data` with
- * the private key corresponding to `signerAddress`
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature An object containing the elliptic curve signature parameters.
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the ECSignature is valid.
- */
- isValidECSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
- assert.isHexString('data', data);
- assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const normalizedSignerAddress = signerAddress.toLowerCase();
-
- const msgHashBuff = ethUtil.toBuffer(data);
- try {
- const pubKey = ethUtil.ecrecover(
- msgHashBuff,
- signature.v,
- ethUtil.toBuffer(signature.r),
- ethUtil.toBuffer(signature.s),
- );
- const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
- const normalizedRetrievedAddress = retrievedAddress.toLowerCase();
- return normalizedRetrievedAddress === normalizedSignerAddress;
- } catch (err) {
- return false;
- }
- },
- /**
- * Signs an order and returns a SignedOrder. First `eth_signTypedData` is requested
- * then a fallback to `eth_sign` if not available on the supplied provider.
- * @param order The Order to sign.
- * @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address
- * must be available via the supplied Provider.
- * @return A SignedOrder containing the order and Elliptic curve signature with Signature Type.
- */
- async ecSignOrderAsync(provider: Provider, order: Order, signerAddress: string): Promise<SignedOrder> {
- assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
- try {
- const signedOrder = await signatureUtils.ecSignTypedDataOrderAsync(provider, order, signerAddress);
- return signedOrder;
- } catch (err) {
- // HACK: We are unable to handle specific errors thrown since provider is not an object
- // under our control. It could be Metamask Web3, Ethers, or any general RPC provider.
- // We check for a user denying the signature request in a way that supports Metamask and
- // Coinbase Wallet. Unfortunately for signers with a different error message,
- // they will receive two signature requests.
- if (err.message.includes('User denied message signature')) {
- throw err;
- }
- const orderHash = orderHashUtils.getOrderHashHex(order);
- const signatureHex = await signatureUtils.ecSignHashAsync(provider, orderHash, signerAddress);
- const signedOrder = {
- ...order,
- signature: signatureHex,
- };
- return signedOrder;
- }
- },
- /**
- * Signs an order using `eth_signTypedData` and returns a SignedOrder.
- * @param order The Order to sign.
- * @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address
- * must be available via the supplied Provider.
- * @return A SignedOrder containing the order and Elliptic curve signature with Signature Type.
- */
- async ecSignTypedDataOrderAsync(provider: Provider, order: Order, signerAddress: string): Promise<SignedOrder> {
- assert.isWeb3Provider('provider', provider);
- assert.isETHAddressHex('signerAddress', signerAddress);
- assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
- const web3Wrapper = new Web3Wrapper(provider);
- await assert.isSenderAddressAsync('signerAddress', signerAddress, web3Wrapper);
- const normalizedSignerAddress = signerAddress.toLowerCase();
- const typedData = eip712Utils.createOrderTypedData(order);
- try {
- const signature = await web3Wrapper.signTypedDataAsync(normalizedSignerAddress, typedData);
- const ecSignatureRSV = parseSignatureHexAsRSV(signature);
- const signatureBuffer = Buffer.concat([
- ethUtil.toBuffer(ecSignatureRSV.v),
- ethUtil.toBuffer(ecSignatureRSV.r),
- ethUtil.toBuffer(ecSignatureRSV.s),
- ethUtil.toBuffer(SignatureType.EIP712),
- ]);
- const signatureHex = `0x${signatureBuffer.toString('hex')}`;
- return {
- ...order,
- signature: signatureHex,
- };
- } catch (err) {
- // Detect if Metamask to transition users to the MetamaskSubprovider
- if ((provider as any).isMetaMask) {
- throw new Error(OrderError.InvalidMetamaskSigner);
- } else {
- throw err;
- }
- }
- },
- /**
- * Signs a hash using `eth_sign` and returns its elliptic curve signature and signature type.
- * @param msgHash Hex encoded message to sign.
- * @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address
- * must be available via the supplied Provider.
- * @return A hex encoded string containing the Elliptic curve signature generated by signing the msgHash and the Signature Type.
- */
- async ecSignHashAsync(provider: Provider, msgHash: string, signerAddress: string): Promise<string> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('msgHash', msgHash);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const web3Wrapper = new Web3Wrapper(provider);
- await assert.isSenderAddressAsync('signerAddress', signerAddress, web3Wrapper);
- const normalizedSignerAddress = signerAddress.toLowerCase();
- const signature = await web3Wrapper.signMessageAsync(normalizedSignerAddress, msgHash);
- const prefixedMsgHashHex = signatureUtils.addSignedMessagePrefix(msgHash);
-
- // HACK: There is no consensus on whether the signatureHex string should be formatted as
- // v + r + s OR r + s + v, and different clients (even different versions of the same client)
- // return the signature params in different orders. In order to support all client implementations,
- // we parse the signature in both ways, and evaluate if either one is a valid signature.
- // r + s + v is the most prevalent format from eth_sign, so we attempt this first.
- // tslint:disable-next-line:custom-no-magic-numbers
- const validVParamValues = [27, 28];
- const ecSignatureRSV = parseSignatureHexAsRSV(signature);
- if (_.includes(validVParamValues, ecSignatureRSV.v)) {
- const isValidRSVSignature = signatureUtils.isValidECSignature(
- prefixedMsgHashHex,
- ecSignatureRSV,
- normalizedSignerAddress,
- );
- if (isValidRSVSignature) {
- const convertedSignatureHex = signatureUtils.convertECSignatureToSignatureHex(ecSignatureRSV);
- return convertedSignatureHex;
- }
- }
- const ecSignatureVRS = parseSignatureHexAsVRS(signature);
- if (_.includes(validVParamValues, ecSignatureVRS.v)) {
- const isValidVRSSignature = signatureUtils.isValidECSignature(
- prefixedMsgHashHex,
- ecSignatureVRS,
- normalizedSignerAddress,
- );
- if (isValidVRSSignature) {
- const convertedSignatureHex = signatureUtils.convertECSignatureToSignatureHex(ecSignatureVRS);
- return convertedSignatureHex;
- }
- }
- // Detect if Metamask to transition users to the MetamaskSubprovider
- if ((provider as any).isMetaMask) {
- throw new Error(OrderError.InvalidMetamaskSigner);
- } else {
- throw new Error(OrderError.InvalidSignature);
- }
- },
- /**
- * Combines ECSignature with V,R,S and the EthSign signature type for use in 0x protocol
- * @param ecSignature The ECSignature of the signed data
- * @return Hex encoded string of signature (v,r,s) with Signature Type
- */
- convertECSignatureToSignatureHex(ecSignature: ECSignature): string {
- const signatureBuffer = Buffer.concat([
- ethUtil.toBuffer(ecSignature.v),
- ethUtil.toBuffer(ecSignature.r),
- ethUtil.toBuffer(ecSignature.s),
- ]);
- const signatureHex = `0x${signatureBuffer.toString('hex')}`;
- const signatureWithType = signatureUtils.convertToSignatureWithType(signatureHex, SignatureType.EthSign);
- return signatureWithType;
- },
- /**
- * Combines the signature proof and the Signature Type.
- * @param signature The hex encoded signature proof
- * @param signatureType The signature type, i.e EthSign, Wallet etc.
- * @return Hex encoded string of signature proof with Signature Type
- */
- convertToSignatureWithType(signature: string, signatureType: SignatureType): string {
- const signatureBuffer = Buffer.concat([ethUtil.toBuffer(signature), ethUtil.toBuffer(signatureType)]);
- const signatureHex = `0x${signatureBuffer.toString('hex')}`;
- return signatureHex;
- },
- /**
- * Adds the relevant prefix to the message being signed.
- * @param message Message to sign
- * @return Prefixed message
- */
- addSignedMessagePrefix(message: string): string {
- assert.isString('message', message);
- const msgBuff = ethUtil.toBuffer(message);
- const prefixedMsgBuff = ethUtil.hashPersonalMessage(msgBuff);
- const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
- return prefixedMsgHex;
- },
- /**
- * Parse a 0x protocol hex-encoded signature string into its ECSignature components
- * @param signature A hex encoded ecSignature 0x Protocol signature
- * @return An ECSignature object with r,s,v parameters
- */
- parseECSignature(signature: string): ECSignature {
- assert.isHexString('signature', signature);
- const ecSignatureTypes = [SignatureType.EthSign, SignatureType.EIP712];
- assert.isOneOfExpectedSignatureTypes(signature, ecSignatureTypes);
-
- // tslint:disable-next-line:custom-no-magic-numbers
- const vrsHex = signature.slice(0, -2);
- const ecSignature = parseSignatureHexAsVRS(vrsHex);
-
- return ecSignature;
- },
-};
-
-function parseValidatorSignature(signature: string): ValidatorSignature {
- assert.isOneOfExpectedSignatureTypes(signature, [SignatureType.Validator]);
- // tslint:disable:custom-no-magic-numbers
- const validatorSignature = {
- validatorAddress: signature.slice(-22, -2),
- signature: signature.slice(0, -22),
- };
- // tslint:enable:custom-no-magic-numbers
- return validatorSignature;
-}
-
-function parseSignatureHexAsVRS(signatureHex: string): ECSignature {
- const signatureBuffer = ethUtil.toBuffer(signatureHex);
- let v = signatureBuffer[0];
- // HACK: Sometimes v is returned as [0, 1] and sometimes as [27, 28]
- // If it is returned as [0, 1], add 27 to both so it becomes [27, 28]
- const lowestValidV = 27;
- const isProperlyFormattedV = v >= lowestValidV;
- if (!isProperlyFormattedV) {
- v += lowestValidV;
- }
- // signatureBuffer contains vrs
- const vEndIndex = 1;
- const rsIndex = 33;
- const r = signatureBuffer.slice(vEndIndex, rsIndex);
- const sEndIndex = 65;
- const s = signatureBuffer.slice(rsIndex, sEndIndex);
- const ecSignature: ECSignature = {
- v,
- r: ethUtil.bufferToHex(r),
- s: ethUtil.bufferToHex(s),
- };
- return ecSignature;
-}
-
-function parseSignatureHexAsRSV(signatureHex: string): ECSignature {
- const { v, r, s } = ethUtil.fromRpcSig(signatureHex);
- const ecSignature: ECSignature = {
- v,
- r: ethUtil.bufferToHex(r),
- s: ethUtil.bufferToHex(s),
- };
- return ecSignature;
-}
diff --git a/packages/order-utils/src/sorting_utils.ts b/packages/order-utils/src/sorting_utils.ts
deleted file mode 100644
index 1de24264f..000000000
--- a/packages/order-utils/src/sorting_utils.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { schemas } from '@0x/json-schemas';
-import { Order } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-
-import { assert } from './assert';
-import { constants } from './constants';
-import { rateUtils } from './rate_utils';
-
-export const sortingUtils = {
- /**
- * Takes an array of orders and sorts them by takerAsset/makerAsset rate in ascending order (best rate first).
- * Adjusts the rate of each order according to the feeRate and takerFee for that order.
- * @param orders An array of objects that extend the Order interface. All orders should specify ZRX as
- * the makerAsset and WETH as the takerAsset.
- * @param feeRate The market rate of ZRX denominated in takerAssetAmount
- * (ex. feeRate is 0.1 takerAsset/ZRX if it takes 1 unit of takerAsset to buy 10 ZRX)
- * Defaults to 0
- * @return The input orders sorted by rate in ascending order
- */
- sortOrdersByFeeAdjustedRate<T extends Order>(orders: T[], feeRate: BigNumber = constants.ZERO_AMOUNT): T[] {
- assert.doesConformToSchema('orders', orders, schemas.ordersSchema);
- assert.isBigNumber('feeRate', feeRate);
- const rateCalculator = (order: Order) => rateUtils.getFeeAdjustedRateOfOrder(order, feeRate);
- const sortedOrders = sortOrders(orders, rateCalculator);
- return sortedOrders;
- },
- /**
- * Takes an array of fee orders (makerAssetData corresponds to ZRX and takerAssetData corresponds to WETH)
- * and sorts them by rate in ascending order (best rate first). Adjusts the rate according to the takerFee.
- * @param feeOrders An array of objects that extend the Order interface. All orders should specify ZRX as
- * the makerAsset and WETH as the takerAsset.
- * @return The input orders sorted by rate in ascending order
- */
- sortFeeOrdersByFeeAdjustedRate<T extends Order>(feeOrders: T[]): T[] {
- assert.doesConformToSchema('feeOrders', feeOrders, schemas.ordersSchema);
- const rateCalculator = rateUtils.getFeeAdjustedRateOfFeeOrder.bind(rateUtils);
- const sortedOrders = sortOrders(feeOrders, rateCalculator);
- return sortedOrders;
- },
-};
-
-type RateCalculator = (order: Order) => BigNumber;
-
-// takes an array of orders, copies them, and sorts the copy based on the rate definition provided by rateCalculator
-function sortOrders<T extends Order>(orders: T[], rateCalculator: RateCalculator): T[] {
- const copiedOrders = _.cloneDeep(orders);
- copiedOrders.sort((firstOrder, secondOrder) => {
- const firstOrderRate = rateCalculator(firstOrder);
- const secondOrderRate = rateCalculator(secondOrder);
- return firstOrderRate.comparedTo(secondOrderRate);
- });
- return copiedOrders;
-}
diff --git a/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts b/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts
deleted file mode 100644
index ae3e36238..000000000
--- a/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-import { AssetProxyId } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-
-import { AbstractBalanceAndProxyAllowanceFetcher } from '../abstract/abstract_balance_and_proxy_allowance_fetcher';
-import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store';
-import { assetDataUtils } from '../asset_data_utils';
-
-/**
- * Copy on read store for balances/proxyAllowances of tokens/accounts
- */
-export class BalanceAndProxyAllowanceLazyStore implements AbstractBalanceAndProxyAllowanceLazyStore {
- private readonly _balanceAndProxyAllowanceFetcher: AbstractBalanceAndProxyAllowanceFetcher;
- private _balance: {
- [assetData: string]: {
- [userAddress: string]: BigNumber;
- };
- };
- private _proxyAllowance: {
- [assetData: string]: {
- [userAddress: string]: BigNumber;
- };
- };
- /**
- * Instantiates a BalanceAndProxyAllowanceLazyStore
- * @param balanceAndProxyAllowanceFetcher Class the implements the AbstractBalanceAndProxyAllowanceFetcher
- * @return Instance of BalanceAndProxyAllowanceLazyStore
- */
- constructor(balanceAndProxyAllowanceFetcher: AbstractBalanceAndProxyAllowanceFetcher) {
- this._balanceAndProxyAllowanceFetcher = balanceAndProxyAllowanceFetcher;
- this._balance = {};
- this._proxyAllowance = {};
- }
- /**
- * Get a users balance of an asset
- * @param assetData AssetData of interest
- * @param userAddress Ethereum address of interest
- */
- public async getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber> {
- if (_.isUndefined(this._balance[assetData]) || _.isUndefined(this._balance[assetData][userAddress])) {
- const balance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(assetData, userAddress);
- this.setBalance(assetData, userAddress, balance);
- }
- const cachedBalance = this._balance[assetData][userAddress];
- return cachedBalance;
- }
- /**
- * Set the balance of an asset for a user
- * @param assetData AssetData of interest
- * @param userAddress Ethereum address of interest
- */
- public setBalance(assetData: string, userAddress: string, balance: BigNumber): void {
- if (_.isUndefined(this._balance[assetData])) {
- this._balance[assetData] = {};
- }
- this._balance[assetData][userAddress] = balance;
- }
- /**
- * Clear the balance of an asset for a user
- * @param assetData AssetData of interest
- * @param userAddress Ethereum address of interest
- */
- public deleteBalance(assetData: string, userAddress: string): void {
- if (!_.isUndefined(this._balance[assetData])) {
- delete this._balance[assetData][userAddress];
- if (_.isEmpty(this._balance[assetData])) {
- delete this._balance[assetData];
- }
- }
- }
- /**
- * Get the 0x asset proxy allowance
- * @param assetData AssetData of interest
- * @param userAddress Ethereum address of interest
- */
- public async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber> {
- if (
- _.isUndefined(this._proxyAllowance[assetData]) ||
- _.isUndefined(this._proxyAllowance[assetData][userAddress])
- ) {
- const proxyAllowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync(
- assetData,
- userAddress,
- );
- this.setProxyAllowance(assetData, userAddress, proxyAllowance);
- }
- const cachedProxyAllowance = this._proxyAllowance[assetData][userAddress];
- return cachedProxyAllowance;
- }
- /**
- * Set the 0x asset proxy allowance
- * @param assetData AssetData of interest
- * @param userAddress Ethereum address of interest
- */
- public setProxyAllowance(assetData: string, userAddress: string, proxyAllowance: BigNumber): void {
- if (_.isUndefined(this._proxyAllowance[assetData])) {
- this._proxyAllowance[assetData] = {};
- }
- this._proxyAllowance[assetData][userAddress] = proxyAllowance;
- }
- /**
- * Clear the 0x asset proxy allowance
- * @param assetData AssetData of interest
- * @param userAddress Ethereum address of interest
- */
- public deleteProxyAllowance(assetData: string, userAddress: string): void {
- if (!_.isUndefined(this._proxyAllowance[assetData])) {
- delete this._proxyAllowance[assetData][userAddress];
- if (_.isEmpty(this._proxyAllowance[assetData])) {
- delete this._proxyAllowance[assetData];
- }
- }
- }
- /**
- * Clear all ERC721 0x proxy allowances a user has on all items of a specific ERC721 contract
- * @param tokenAddress ERc721 token address
- * @param userAddress Owner Ethereum address
- */
- public deleteAllERC721ProxyAllowance(tokenAddress: string, userAddress: string): void {
- for (const assetData in this._proxyAllowance) {
- if (this._proxyAllowance.hasOwnProperty(assetData)) {
- const decodedAssetData = assetDataUtils.decodeERC721AssetData(assetData);
- if (
- decodedAssetData.assetProxyId === AssetProxyId.ERC721 &&
- decodedAssetData.tokenAddress === tokenAddress &&
- !_.isUndefined(this._proxyAllowance[assetData][userAddress])
- ) {
- delete this._proxyAllowance[assetData][userAddress];
- }
- }
- }
- }
- /**
- * Delete all balances & allowances
- */
- public deleteAll(): void {
- this._balance = {};
- this._proxyAllowance = {};
- }
-}
diff --git a/packages/order-utils/src/store/order_filled_cancelled_lazy_store.ts b/packages/order-utils/src/store/order_filled_cancelled_lazy_store.ts
deleted file mode 100644
index afd6f1108..000000000
--- a/packages/order-utils/src/store/order_filled_cancelled_lazy_store.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import { SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-
-import { AbstractOrderFilledCancelledFetcher } from '../abstract/abstract_order_filled_cancelled_fetcher';
-import { AbstractOrderFilledCancelledLazyStore } from '../abstract/abstract_order_filled_cancelled_lazy_store';
-import { orderHashUtils } from '../order_hash';
-
-/**
- * Copy on read store for balances/proxyAllowances of tokens/accounts
- */
-export class OrderFilledCancelledLazyStore implements AbstractOrderFilledCancelledLazyStore {
- private readonly _orderFilledCancelledFetcher: AbstractOrderFilledCancelledFetcher;
- private _filledTakerAmount: {
- [orderHash: string]: BigNumber;
- };
- private _isCancelled: {
- [orderHash: string]: boolean;
- };
- /**
- * Instantiate a OrderFilledCancelledLazyStore
- * @param orderFilledCancelledFetcher Class instance that implements the AbstractOrderFilledCancelledFetcher
- * @returns An instance of OrderFilledCancelledLazyStore
- */
- constructor(orderFilledCancelledFetcher: AbstractOrderFilledCancelledFetcher) {
- this._orderFilledCancelledFetcher = orderFilledCancelledFetcher;
- this._filledTakerAmount = {};
- this._isCancelled = {};
- }
- /**
- * Get the filledTakerAssetAmount of an order
- * @param orderHash OrderHash from order of interest
- * @return filledTakerAssetAmount
- */
- public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber> {
- if (_.isUndefined(this._filledTakerAmount[orderHash])) {
- const filledTakerAmount = await this._orderFilledCancelledFetcher.getFilledTakerAmountAsync(orderHash);
- this.setFilledTakerAmount(orderHash, filledTakerAmount);
- }
- const cachedFilledTakerAmount = this._filledTakerAmount[orderHash];
- return cachedFilledTakerAmount;
- }
- /**
- * Set the filledTakerAssetAmount of an order
- * @param orderHash OrderHash from order of interest
- * @param filledTakerAmount Desired filledTakerAssetAmount
- */
- public setFilledTakerAmount(orderHash: string, filledTakerAmount: BigNumber): void {
- this._filledTakerAmount[orderHash] = filledTakerAmount;
- }
- /**
- * Clear the filledTakerAssetAmount of an order
- * @param orderHash OrderHash from order of interest
- */
- public deleteFilledTakerAmount(orderHash: string): void {
- delete this._filledTakerAmount[orderHash];
- }
- /**
- * Check if an order has been cancelled
- * @param orderHash OrderHash from order of interest
- * @return Whether the order has been cancelled
- */
- public async getIsCancelledAsync(signedOrder: SignedOrder): Promise<boolean> {
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- if (_.isUndefined(this._isCancelled[orderHash])) {
- const isCancelled = await this._orderFilledCancelledFetcher.isOrderCancelledAsync(signedOrder);
- this.setIsCancelled(orderHash, isCancelled);
- }
- const cachedIsCancelled = this._isCancelled[orderHash]; // tslint:disable-line:boolean-naming
- return cachedIsCancelled;
- }
- /**
- * Set whether an order has been cancelled or not
- * @param orderHash OrderHash from order of interest
- * @param isCancelled Whether this order should be cancelled or not
- */
- public setIsCancelled(orderHash: string, isCancelled: boolean): void {
- this._isCancelled[orderHash] = isCancelled;
- }
- /**
- * Clear whether the order has been cancelled if already set
- * @param orderHash OrderHash from order of interest
- */
- public deleteIsCancelled(orderHash: string): void {
- delete this._isCancelled[orderHash];
- }
- /**
- * Clear all filled/cancelled state
- */
- public deleteAll(): void {
- this.deleteAllFilled();
- this.deleteAllIsCancelled();
- }
- /**
- * Clear all cancelled state
- */
- public deleteAllIsCancelled(): void {
- this._isCancelled = {};
- }
- /**
- * Clear all filled state
- */
- public deleteAllFilled(): void {
- this._filledTakerAmount = {};
- }
- /**
- * Get the ZRX assetData
- */
- public getZRXAssetData(): string {
- const zrxAssetData = this._orderFilledCancelledFetcher.getZRXAssetData();
- return zrxAssetData;
- }
-}
diff --git a/packages/order-utils/src/types.ts b/packages/order-utils/src/types.ts
deleted file mode 100644
index 55ec553db..000000000
--- a/packages/order-utils/src/types.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { BigNumber } from '@0x/utils';
-
-export enum OrderError {
- InvalidSignature = 'INVALID_SIGNATURE',
- InvalidMetamaskSigner = "MetaMask provider must be wrapped in a MetamaskSubprovider (from the '@0x/subproviders' package) in order to work with this method.",
-}
-
-export enum TradeSide {
- Maker = 'maker',
- Taker = 'taker',
-}
-
-export enum TransferType {
- Trade = 'trade',
- Fee = 'fee',
-}
-
-export interface CreateOrderOpts {
- takerAddress?: string;
- senderAddress?: string;
- makerFee?: BigNumber;
- takerFee?: BigNumber;
- feeRecipientAddress?: string;
- salt?: BigNumber;
- expirationTimeSeconds?: BigNumber;
-}
-
-/**
- * remainingFillableMakerAssetAmount: An array of BigNumbers corresponding to the `orders` parameter.
- * You can use `OrderStateUtils` `@0x/order-utils` to perform blockchain lookups for these values.
- * Defaults to `makerAssetAmount` values from the orders param.
- * slippageBufferAmount: An additional amount of makerAsset to be covered by the result in case of trade collisions or partial fills.
- * Defaults to 0
- */
-export interface FindOrdersThatCoverMakerAssetFillAmountOpts {
- remainingFillableMakerAssetAmounts?: BigNumber[];
- slippageBufferAmount?: BigNumber;
-}
-
-/**
- * remainingFillableMakerAssetAmount: An array of BigNumbers corresponding to the `orders` parameter.
- * You can use `OrderStateUtils` `@0x/order-utils` to perform blockchain lookups for these values.
- * Defaults to `makerAssetAmount` values from the orders param.
- * remainingFillableFeeAmounts: An array of BigNumbers corresponding to the feeOrders parameter.
- * You can use OrderStateUtils @0x/order-utils to perform blockchain lookups for these values.
- * Defaults to `makerAssetAmount` values from the feeOrders param.
- * slippageBufferAmount: An additional amount of fee to be covered by the result in case of trade collisions or partial fills.
- * Defaults to 0
- */
-export interface FindFeeOrdersThatCoverFeesForTargetOrdersOpts {
- remainingFillableMakerAssetAmounts?: BigNumber[];
- remainingFillableFeeAmounts?: BigNumber[];
- slippageBufferAmount?: BigNumber;
-}
-
-export interface FeeOrdersAndRemainingFeeAmount<T> {
- resultFeeOrders: T[];
- feeOrdersRemainingFillableMakerAssetAmounts: BigNumber[];
- remainingFeeAmount: BigNumber;
-}
-
-export interface OrdersAndRemainingFillAmount<T> {
- resultOrders: T[];
- ordersRemainingFillableMakerAssetAmounts: BigNumber[];
- remainingFillAmount: BigNumber;
-}
diff --git a/packages/order-utils/src/utils.ts b/packages/order-utils/src/utils.ts
deleted file mode 100644
index 64195dbed..000000000
--- a/packages/order-utils/src/utils.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { BigNumber } from '@0x/utils';
-
-export const utils = {
- getSignatureTypeIndexIfExists(signature: string): number {
- // tslint:disable-next-line:custom-no-magic-numbers
- const signatureTypeHex = signature.slice(-2);
- const base = 16;
- const signatureTypeInt = parseInt(signatureTypeHex, base);
- return signatureTypeInt;
- },
- getCurrentUnixTimestampSec(): BigNumber {
- const milisecondsInSecond = 1000;
- return new BigNumber(Date.now() / milisecondsInSecond).integerValue();
- },
- getPartialAmountFloor(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
- const fillMakerTokenAmount = numerator
- .multipliedBy(target)
- .div(denominator)
- .integerValue(0);
- return fillMakerTokenAmount;
- },
-};