aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-utils')
-rw-r--r--packages/order-utils/.npmignore7
-rw-r--r--packages/order-utils/CHANGELOG.json424
-rw-r--r--packages/order-utils/CHANGELOG.md172
-rw-r--r--packages/order-utils/README.md65
-rw-r--r--packages/order-utils/coverage/.gitkeep0
-rw-r--r--packages/order-utils/package.json76
-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
-rw-r--r--packages/order-utils/test/assert_test.ts34
-rw-r--r--packages/order-utils/test/asset_data_utils_test.ts110
-rw-r--r--packages/order-utils/test/eip712_utils_test.ts44
-rw-r--r--packages/order-utils/test/exchange_transfer_simulator_test.ts174
-rw-r--r--packages/order-utils/test/market_utils_test.ts267
-rw-r--r--packages/order-utils/test/order_hash_test.ts77
-rw-r--r--packages/order-utils/test/order_state_utils_test.ts145
-rw-r--r--packages/order-utils/test/order_validation_utils_test.ts70
-rw-r--r--packages/order-utils/test/rate_utils_test.ts55
-rw-r--r--packages/order-utils/test/remaining_fillable_calculator_test.ts246
-rw-r--r--packages/order-utils/test/signature_utils_test.ts324
-rw-r--r--packages/order-utils/test/sorting_utils_test.ts67
-rw-r--r--packages/order-utils/test/utils/chai_setup.ts13
-rw-r--r--packages/order-utils/test/utils/simple_erc20_balance_and_proxy_allowance_fetcher.ts25
-rw-r--r--packages/order-utils/test/utils/test_order_factory.ts33
-rw-r--r--packages/order-utils/test/utils/web3_wrapper.ts8
-rw-r--r--packages/order-utils/tsconfig.json8
-rw-r--r--packages/order-utils/tslint.json3
-rw-r--r--packages/order-utils/typedoc-tsconfig.json7
51 files changed, 0 insertions, 5260 deletions
diff --git a/packages/order-utils/.npmignore b/packages/order-utils/.npmignore
deleted file mode 100644
index 89302c908..000000000
--- a/packages/order-utils/.npmignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.*
-yarn-error.log
-/scripts/
-/generated_docs/
-/src/
-tsconfig.json
-/lib/monorepo_scripts/
diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json
deleted file mode 100644
index 08d88da5b..000000000
--- a/packages/order-utils/CHANGELOG.json
+++ /dev/null
@@ -1,424 +0,0 @@
-[
- {
- "version": "4.0.0",
- "changes": [
- {
- "note": "Upgrade the bignumber.js to v8.0.2",
- "pr": 1517
- }
- ]
- },
- {
- "timestamp": 1547561734,
- "version": "3.1.2",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1547225310,
- "version": "3.1.1",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "version": "3.1.0",
- "changes": [
- {
- "note": "Use new ABI encoder, add encoding/decoding logic for MultiAsset assetData, and add information to return values in orderStateUtils",
- "pr": 1363
- }
- ],
- "timestamp": 1547040760
- },
- {
- "version": "3.0.7",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ],
- "timestamp": 1544739608
- },
- {
- "version": "3.0.6",
- "changes": [
- {
- "note": "Fix bug in wallet signature type verification",
- "pr": 1414
- }
- ],
- "timestamp": 1544570656
- },
- {
- "timestamp": 1544482891,
- "version": "3.0.5",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1543401373,
- "version": "3.0.4",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1542821676,
- "version": "3.0.3",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1542208198,
- "version": "3.0.2",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1542134075,
- "version": "3.0.1",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "version": "3.0.0",
- "changes": [
- {
- "note": "Add signature validation, regular cancellation and `cancelledUpTo` checks to `validateOrderFillableOrThrowAsync`",
- "pr": 1235
- },
- {
- "note": "Improved the errors thrown by `validateOrderFillableOrThrowAsync` by making them more descriptive",
- "pr": 1235
- },
- {
- "note": "Throw previously swallowed network errors when calling `validateOrderFillableOrThrowAsync` (see issue: #1218)",
- "pr": 1235
- },
- {
- "note": "Modified the `AbstractOrderFilledCancelledFetcher` interface slightly such that `isOrderCancelledAsync` accepts a `signedOrder` instead of an `orderHash` param",
- "pr": 1235
- }
- ],
- "timestamp": 1542028948
- },
- {
- "version": "2.0.1",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ],
- "timestamp": 1541740904
- },
- {
- "version": "2.0.0",
- "changes": [
- {
- "note": "Added `ecSignOrderAsync` to first sign an order using `eth_signTypedData` and fallback to `eth_sign`.",
- "pr": 1102
- },
- {
- "note": "Added `ecSignTypedDataOrderAsync` to sign an order exclusively using `eth_signTypedData`.",
- "pr": 1102
- },
- {
- "note": "Rename `ecSignOrderHashAsync` to `ecSignHashAsync` removing `SignerType` parameter.",
- "pr": 1102
- },
- {
- "note": "Use `AssetData` union type for function return values.",
- "pr": 1131
- }
- ],
- "timestamp": 1539871071
- },
- {
- "version": "1.0.7",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ],
- "timestamp": 1538693146
- },
- {
- "version": "1.0.6",
- "changes": [
- {
- "note": "Add signerAddress normalization to `isValidECSignature` to avoid `invalid address recovery` error if caller supplies a checksummed address",
- "pr": 1096
- }
- ],
- "timestamp": 1538157789
- },
- {
- "timestamp": 1537907159,
- "version": "1.0.5",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1537875740,
- "version": "1.0.4",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1537541580,
- "version": "1.0.3",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "version": "1.0.2",
- "changes": [
- {
- "note": "Drastically reduce the bundle size by removing unused parts of included contract artifacts."
- }
- ],
- "timestamp": 1537369748
- },
- {
- "version": "1.0.1",
- "changes": [
- {
- "note": "Export `orderParsingUtils`",
- "pr": 1044
- }
- ],
- "timestamp": 1536142250
- },
- {
- "version": "1.0.1-rc.6",
- "changes": [
- {
- "note": "Fix missing `BlockParamLiteral` type import issue"
- }
- ],
- "timestamp": 1535377027
- },
- {
- "version": "1.0.1-rc.5",
- "changes": [
- {
- "note": "Remove Caller and Trezor SignatureTypes",
- "pr": 1015
- }
- ]
- },
- {
- "version": "1.0.1-rc.4",
- "changes": [
- {
- "note": "Remove rounding error being thrown when maker amount is very small",
- "pr": 959
- },
- {
- "note": "Added rateUtils and sortingUtils",
- "pr": 953
- },
- {
- "note": "Update marketUtils api such that all optional parameters are bundled into one optional param and more defaults are provided",
- "pr": 954
- },
- {
- "note": "Instead of exporting signature util methods individually, they are now exported as `signatureUtils`",
- "pr": 924
- },
- {
- "note": "Export types: `SignedOrder`, `Order`, `OrderRelevantState`, `OrderState`, `ECSignature`, `ERC20AssetData`, `ERC721AssetData`, `AssetProxyId`, `SignerType`, `SignatureType`, `OrderStateValid`, `OrderStateInvalid`, `ExchangeContractErrs`, `TradeSide`, `TransferType`, `FindFeeOrdersThatCoverFeesForTargetOrdersOpts`, `FindOrdersThatCoverMakerAssetFillAmountOpts`, `FeeOrdersAndRemainingFeeAmount`, `OrdersAndRemainingFillAmount`, `Provider`, `JSONRPCRequestPayload`, `JSONRPCErrorCallback` and `JSONRPCResponsePayload`",
- "pr": 924
- },
- {
- "note": "Rename `resultOrders` to `resultFeeOrders` for object returned by `findFeeOrdersThatCoverFeesForTargetOrders` in `marketUtils` api",
- "pr": 997
- },
- {
- "note": "Make `sortFeeOrdersByFeeAdjustedRate` in `sortingUtils` generic",
- "pr": 997
- },
- {
- "note": "Update `findFeeOrdersThatCoverFeesForTargetOrders` to round the the nearest integer when calculating required fees",
- "pr": 997
- }
- ],
- "timestamp": 1535133899
- },
- {
- "version": "1.0.1-rc.3",
- "changes": [
- {
- "pr": 914,
- "note": "Update ecSignOrderHashAsync to return signature string with signature type byte. Removes messagePrefixOpts."
- },
- {
- "note": "Added a synchronous `createOrder` method in `orderFactory`, updated public interfaces to support some optional parameters",
- "pr": 936
- },
- {
- "note": "Added marketUtils",
- "pr": 937
- },
- {
- "note": "Dependencies updated"
- }
- ],
- "timestamp": 1534210131
- },
- {
- "version": "1.0.1-rc.2",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ],
- "timestamp": 1532619515
- },
- {
- "version": "1.0.1-rc.1",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ],
- "timestamp": 1532605697
- },
- {
- "version": "1.0.0",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ],
- "timestamp": 1532357734
- },
- {
- "version": "1.0.0-rc.2",
- "changes": [
- {
- "note": "Upgrade ethereumjs-abi dep including a fix so that addresses starting with 0 are properly decoded by `decodeERC20AssetData`"
- }
- ],
- "timestamp": 1532357734
- },
- {
- "timestamp": 1532043000,
- "version": "1.0.0-rc.1",
- "changes": [
- {
- "note": "Refactor to work with V2 of 0x protocol",
- "pr": 636
- },
- {
- "note": "Export parseECSignature method",
- "pr": 684
- },
- {
- "note": "Handle Typed Arrays when hashing data",
- "pr": 894
- }
- ]
- },
- {
- "timestamp": 1531919263,
- "version": "0.0.9",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1531149657,
- "version": "0.0.8",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1529397769,
- "version": "0.0.7",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1527616612,
- "version": "0.0.6",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "version": "0.0.5",
- "changes": [
- {
- "note": "Add orderStateUtils, a module for computing order state needed to decide if an order is still valid"
- }
- ],
- "timestamp": 1527008794
- },
- {
- "timestamp": 1525477860,
- "version": "0.0.4",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1525453812,
- "version": "0.0.3",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- },
- {
- "timestamp": 1525428773,
- "version": "0.0.2",
- "changes": [
- {
- "note": "Dependencies updated"
- }
- ]
- }
-]
diff --git a/packages/order-utils/CHANGELOG.md b/packages/order-utils/CHANGELOG.md
deleted file mode 100644
index c82458f2e..000000000
--- a/packages/order-utils/CHANGELOG.md
+++ /dev/null
@@ -1,172 +0,0 @@
-<!--
-changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
-Edit the package's CHANGELOG.json file only.
--->
-
-CHANGELOG
-
-## v3.1.2 - _January 15, 2019_
-
- * Dependencies updated
-
-## v3.1.1 - _January 11, 2019_
-
- * Dependencies updated
-
-## v3.1.0 - _January 9, 2019_
-
- * Use new ABI encoder, add encoding/decoding logic for MultiAsset assetData, and add information to return values in orderStateUtils (#1363)
-
-## v3.0.7 - _December 13, 2018_
-
- * Dependencies updated
-
-## v3.0.6 - _December 11, 2018_
-
- * Fix bug in wallet signature type verification (#1414)
-
-## v3.0.5 - _December 10, 2018_
-
- * Dependencies updated
-
-## v3.0.4 - _November 28, 2018_
-
- * Dependencies updated
-
-## v3.0.3 - _November 21, 2018_
-
- * Dependencies updated
-
-## v3.0.2 - _November 14, 2018_
-
- * Dependencies updated
-
-## v3.0.1 - _November 13, 2018_
-
- * Dependencies updated
-
-## v3.0.0 - _November 12, 2018_
-
- * Add signature validation, regular cancellation and `cancelledUpTo` checks to `validateOrderFillableOrThrowAsync` (#1235)
- * Improved the errors thrown by `validateOrderFillableOrThrowAsync` by making them more descriptive (#1235)
- * Throw previously swallowed network errors when calling `validateOrderFillableOrThrowAsync` (see issue: #1218) (#1235)
- * Modified the `AbstractOrderFilledCancelledFetcher` interface slightly such that `isOrderCancelledAsync` accepts a `signedOrder` instead of an `orderHash` param (#1235)
-
-## v2.0.1 - _November 9, 2018_
-
- * Dependencies updated
-
-## v2.0.0 - _October 18, 2018_
-
- * Added `ecSignOrderAsync` to first sign an order using `eth_signTypedData` and fallback to `eth_sign`. (#1102)
- * Added `ecSignTypedDataOrderAsync` to sign an order exclusively using `eth_signTypedData`. (#1102)
- * Rename `ecSignOrderHashAsync` to `ecSignHashAsync` removing `SignerType` parameter. (#1102)
- * Use `AssetData` union type for function return values. (#1131)
-
-## v1.0.7 - _October 4, 2018_
-
- * Dependencies updated
-
-## v1.0.6 - _September 28, 2018_
-
- * Add signerAddress normalization to `isValidECSignature` to avoid `invalid address recovery` error if caller supplies a checksummed address (#1096)
-
-## v1.0.5 - _September 25, 2018_
-
- * Dependencies updated
-
-## v1.0.4 - _September 25, 2018_
-
- * Dependencies updated
-
-## v1.0.3 - _September 21, 2018_
-
- * Dependencies updated
-
-## v1.0.2 - _September 19, 2018_
-
- * Drastically reduce the bundle size by removing unused parts of included contract artifacts.
-
-## v1.0.1 - _September 5, 2018_
-
- * Export `orderParsingUtils` (#1044)
-
-## v1.0.1-rc.6 - _August 27, 2018_
-
- * Fix missing `BlockParamLiteral` type import issue
-
-## v1.0.1-rc.5 - _Invalid date_
-
- * Remove Caller and Trezor SignatureTypes (#1015)
-
-## v1.0.1-rc.4 - _August 24, 2018_
-
- * Remove rounding error being thrown when maker amount is very small (#959)
- * Added rateUtils and sortingUtils (#953)
- * Update marketUtils api such that all optional parameters are bundled into one optional param and more defaults are provided (#954)
- * Instead of exporting signature util methods individually, they are now exported as `signatureUtils` (#924)
- * Export types: `SignedOrder`, `Order`, `OrderRelevantState`, `OrderState`, `ECSignature`, `ERC20AssetData`, `ERC721AssetData`, `AssetProxyId`, `SignerType`, `SignatureType`, `OrderStateValid`, `OrderStateInvalid`, `ExchangeContractErrs`, `TradeSide`, `TransferType`, `FindFeeOrdersThatCoverFeesForTargetOrdersOpts`, `FindOrdersThatCoverMakerAssetFillAmountOpts`, `FeeOrdersAndRemainingFeeAmount`, `OrdersAndRemainingFillAmount`, `Provider`, `JSONRPCRequestPayload`, `JSONRPCErrorCallback` and `JSONRPCResponsePayload` (#924)
- * Rename `resultOrders` to `resultFeeOrders` for object returned by `findFeeOrdersThatCoverFeesForTargetOrders` in `marketUtils` api (#997)
- * Make `sortFeeOrdersByFeeAdjustedRate` in `sortingUtils` generic (#997)
- * Update `findFeeOrdersThatCoverFeesForTargetOrders` to round the the nearest integer when calculating required fees (#997)
-
-## v1.0.1-rc.3 - _August 14, 2018_
-
- * Update ecSignOrderHashAsync to return signature string with signature type byte. Removes messagePrefixOpts. (#914)
- * Added a synchronous `createOrder` method in `orderFactory`, updated public interfaces to support some optional parameters (#936)
- * Added marketUtils (#937)
- * Dependencies updated
-
-## v1.0.1-rc.2 - _July 26, 2018_
-
- * Dependencies updated
-
-## v1.0.1-rc.1 - _July 26, 2018_
-
- * Dependencies updated
-
-## v1.0.0 - _July 23, 2018_
-
- * Dependencies updated
-
-## v1.0.0-rc.2 - _July 23, 2018_
-
- * Upgrade ethereumjs-abi dep including a fix so that addresses starting with 0 are properly decoded by `decodeERC20AssetData`
-
-## v1.0.0-rc.1 - _July 19, 2018_
-
- * Refactor to work with V2 of 0x protocol (#636)
- * Export parseECSignature method (#684)
- * Handle Typed Arrays when hashing data (#894)
-
-## v0.0.9 - _July 18, 2018_
-
- * Dependencies updated
-
-## v0.0.8 - _July 9, 2018_
-
- * Dependencies updated
-
-## v0.0.7 - _June 19, 2018_
-
- * Dependencies updated
-
-## v0.0.6 - _May 29, 2018_
-
- * Dependencies updated
-
-## v0.0.5 - _May 22, 2018_
-
- * Add orderStateUtils, a module for computing order state needed to decide if an order is still valid
-
-## v0.0.4 - _May 4, 2018_
-
- * Dependencies updated
-
-## v0.0.3 - _May 4, 2018_
-
- * Dependencies updated
-
-## v0.0.2 - _May 4, 2018_
-
- * Dependencies updated
diff --git a/packages/order-utils/README.md b/packages/order-utils/README.md
deleted file mode 100644
index 4a8287098..000000000
--- a/packages/order-utils/README.md
+++ /dev/null
@@ -1,65 +0,0 @@
-## @0x/order-utils
-
-0x order-related utilities for those developing on top of 0x protocol.
-
-### Read the [Documentation](https://0xproject.com/docs/order-utils).
-
-## Installation
-
-```bash
-yarn add @0x/order-utils
-```
-
-If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`:
-
-```json
-"compilerOptions": {
- "typeRoots": ["node_modules/@0x/typescript-typings/types", "node_modules/@types"],
-}
-```
-
-## Contributing
-
-We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository.
-
-Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
-
-### Install dependencies
-
-If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
-
-```bash
-yarn config set workspaces-experimental true
-```
-
-Then install dependencies
-
-```bash
-yarn install
-```
-
-### Build
-
-To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
-
-```bash
-PKG=@0x/order-utils yarn build
-```
-
-Or continuously rebuild on change:
-
-```bash
-PKG=@0x/order-utils yarn watch
-```
-
-### Clean
-
-```bash
-yarn clean
-```
-
-### Lint
-
-```bash
-yarn lint
-```
diff --git a/packages/order-utils/coverage/.gitkeep b/packages/order-utils/coverage/.gitkeep
deleted file mode 100644
index e69de29bb..000000000
--- a/packages/order-utils/coverage/.gitkeep
+++ /dev/null
diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json
deleted file mode 100644
index 7a4d4aa84..000000000
--- a/packages/order-utils/package.json
+++ /dev/null
@@ -1,76 +0,0 @@
-{
- "name": "@0x/order-utils",
- "version": "3.1.2",
- "engines": {
- "node": ">=6.12"
- },
- "description": "0x order utils",
- "main": "lib/src/index.js",
- "types": "lib/src/index.d.ts",
- "scripts": {
- "build": "yarn tsc -b",
- "build:ci": "yarn build",
- "test": "yarn run_mocha",
- "rebuild_and_test": "run-s build test",
- "test:circleci": "yarn test:coverage",
- "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --bail --exit",
- "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
- "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
- "clean": "shx rm -rf lib generated_docs",
- "lint": "tslint --format stylish --project .",
- "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
- },
- "config": {
- "postpublish": {
- "assets": []
- }
- },
- "license": "Apache-2.0",
- "repository": {
- "type": "git",
- "url": "https://github.com/0xProject/0x-monorepo.git"
- },
- "bugs": {
- "url": "https://github.com/0xProject/0x-monorepo/issues"
- },
- "homepage": "https://github.com/0xProject/0x-monorepo/packages/order-utils/README.md",
- "devDependencies": {
- "@0x/dev-utils": "^1.0.24",
- "@0x/tslint-config": "^2.0.2",
- "@types/bn.js": "^4.11.0",
- "@types/lodash": "4.14.104",
- "chai": "^4.0.1",
- "chai-as-promised": "^7.1.0",
- "chai-bignumber": "^3.0.0",
- "dirty-chai": "^2.0.1",
- "make-promises-safe": "^1.1.0",
- "mocha": "^4.1.0",
- "npm-run-all": "^4.1.2",
- "shx": "^0.2.2",
- "sinon": "^4.0.0",
- "tslint": "5.11.0",
- "typedoc": "0.13.0",
- "typescript": "3.0.1"
- },
- "dependencies": {
- "@0x/abi-gen-wrappers": "^2.2.0",
- "@0x/assert": "^1.0.23",
- "@0x/base-contract": "^3.0.13",
- "@0x/contract-artifacts": "^1.3.0",
- "@0x/json-schemas": "^2.1.7",
- "@0x/types": "^1.5.2",
- "@0x/typescript-typings": "^3.0.8",
- "@0x/utils": "^3.0.1",
- "@0x/web3-wrapper": "^3.2.4",
- "@types/node": "*",
- "bn.js": "^4.11.8",
- "ethereum-types": "^1.1.6",
- "ethereumjs-abi": "0.6.5",
- "ethereumjs-util": "^5.1.1",
- "ethers": "~4.0.4",
- "lodash": "^4.17.5"
- },
- "publishConfig": {
- "access": "public"
- }
-}
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;
- },
-};
diff --git a/packages/order-utils/test/assert_test.ts b/packages/order-utils/test/assert_test.ts
deleted file mode 100644
index 631971787..000000000
--- a/packages/order-utils/test/assert_test.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import * as chai from 'chai';
-import 'mocha';
-
-import { assert } from '../src/assert';
-
-import { chaiSetup } from './utils/chai_setup';
-import { web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('Assertion library', () => {
- describe('#isSenderAddressHexAsync', () => {
- it('throws when address is invalid', async () => {
- const address = '0xdeadbeef';
- const varName = 'address';
- return expect(assert.isSenderAddressAsync(varName, address, web3Wrapper)).to.be.rejectedWith(
- `Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`,
- );
- });
- it('throws when address is unavailable', async () => {
- const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
- const varName = 'address';
- return expect(assert.isSenderAddressAsync(varName, validUnrelatedAddress, web3Wrapper)).to.be.rejectedWith(
- `Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
- );
- });
- it("doesn't throw if address is available", async () => {
- const availableAddress = (await web3Wrapper.getAvailableAddressesAsync())[0];
- const varName = 'address';
- return expect(assert.isSenderAddressAsync(varName, availableAddress, web3Wrapper)).to.become(undefined);
- });
- });
-});
diff --git a/packages/order-utils/test/asset_data_utils_test.ts b/packages/order-utils/test/asset_data_utils_test.ts
deleted file mode 100644
index c498c5a00..000000000
--- a/packages/order-utils/test/asset_data_utils_test.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-import * as chai from 'chai';
-
-import { AssetProxyId, ERC721AssetData } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-
-import { assetDataUtils } from '../src/asset_data_utils';
-
-import { chaiSetup } from './utils/chai_setup';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-const KNOWN_ERC20_ENCODING = {
- address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
- assetData: '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48',
-};
-const KNOWN_ERC721_ENCODING = {
- address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
- tokenId: new BigNumber(1),
- assetData:
- '0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001',
-};
-const KNOWN_MULTI_ASSET_ENCODING = {
- amounts: [new BigNumber(1), new BigNumber(1)],
- nestedAssetData: [KNOWN_ERC20_ENCODING.assetData, KNOWN_ERC721_ENCODING.assetData],
- assetData:
- '0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000',
-};
-
-describe('assetDataUtils', () => {
- it('should encode ERC20', () => {
- const assetData = assetDataUtils.encodeERC20AssetData(KNOWN_ERC20_ENCODING.address);
- expect(assetData).to.equal(KNOWN_ERC20_ENCODING.assetData);
- });
- it('should decode ERC20', () => {
- const decodedAssetData = assetDataUtils.decodeERC20AssetData(KNOWN_ERC20_ENCODING.assetData);
- expect(decodedAssetData.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
- expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.ERC20);
- });
- it('should encode ERC721', () => {
- const assetData = assetDataUtils.encodeERC721AssetData(
- KNOWN_ERC721_ENCODING.address,
- KNOWN_ERC721_ENCODING.tokenId,
- );
- expect(assetData).to.equal(KNOWN_ERC721_ENCODING.assetData);
- });
- it('should decode ERC721', () => {
- const decodedAssetData = assetDataUtils.decodeERC721AssetData(KNOWN_ERC721_ENCODING.assetData);
- expect(decodedAssetData.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
- expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.ERC721);
- expect(decodedAssetData.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
- });
- it('should encode ERC20 and ERC721 multiAssetData', () => {
- const assetData = assetDataUtils.encodeMultiAssetData(
- KNOWN_MULTI_ASSET_ENCODING.amounts,
- KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
- );
- expect(assetData).to.equal(KNOWN_MULTI_ASSET_ENCODING.assetData);
- });
- it('should decode ERC20 and ERC721 multiAssetData', () => {
- const decodedAssetData = assetDataUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData);
- expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
- expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts);
- expect(decodedAssetData.nestedAssetData).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.nestedAssetData);
- });
- it('should recursively decode ERC20 and ERC721 multiAssetData', () => {
- const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(KNOWN_MULTI_ASSET_ENCODING.assetData);
- expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
- expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts);
- const decodedErc20AssetData = decodedAssetData.nestedAssetData[0];
- // tslint:disable-next-line:no-unnecessary-type-assertion
- const decodedErc721AssetData = decodedAssetData.nestedAssetData[1] as ERC721AssetData;
- expect(decodedErc20AssetData.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
- expect(decodedErc20AssetData.assetProxyId).to.equal(AssetProxyId.ERC20);
- expect(decodedErc721AssetData.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
- expect(decodedErc721AssetData.assetProxyId).to.equal(AssetProxyId.ERC721);
- expect(decodedErc721AssetData.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
- });
- it('should recursively decode nested assetData within multiAssetData', () => {
- const amounts = [new BigNumber(1), new BigNumber(1), new BigNumber(2)];
- const nestedAssetData = [
- KNOWN_ERC20_ENCODING.assetData,
- KNOWN_ERC721_ENCODING.assetData,
- KNOWN_MULTI_ASSET_ENCODING.assetData,
- ];
- const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
- const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(assetData);
- expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
- const expectedAmounts = [new BigNumber(1), new BigNumber(1), new BigNumber(2), new BigNumber(2)];
- expect(decodedAssetData.amounts).to.deep.equal(expectedAmounts);
- const expectedLength = 4;
- expect(decodedAssetData.nestedAssetData.length).to.be.equal(expectedLength);
- const decodedErc20AssetData1 = decodedAssetData.nestedAssetData[0];
- // tslint:disable-next-line:no-unnecessary-type-assertion
- const decodedErc721AssetData1 = decodedAssetData.nestedAssetData[1] as ERC721AssetData;
- const decodedErc20AssetData2 = decodedAssetData.nestedAssetData[2];
- // tslint:disable-next-line:no-unnecessary-type-assertion
- const decodedErc721AssetData2 = decodedAssetData.nestedAssetData[3] as ERC721AssetData;
- expect(decodedErc20AssetData1.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
- expect(decodedErc20AssetData1.assetProxyId).to.equal(AssetProxyId.ERC20);
- expect(decodedErc721AssetData1.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
- expect(decodedErc721AssetData1.assetProxyId).to.equal(AssetProxyId.ERC721);
- expect(decodedErc721AssetData1.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
- expect(decodedErc20AssetData2.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
- expect(decodedErc20AssetData2.assetProxyId).to.equal(AssetProxyId.ERC20);
- expect(decodedErc721AssetData2.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
- expect(decodedErc721AssetData2.assetProxyId).to.equal(AssetProxyId.ERC721);
- expect(decodedErc721AssetData2.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
- });
-});
diff --git a/packages/order-utils/test/eip712_utils_test.ts b/packages/order-utils/test/eip712_utils_test.ts
deleted file mode 100644
index a54e49958..000000000
--- a/packages/order-utils/test/eip712_utils_test.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import 'mocha';
-
-import { constants } from '../src/constants';
-import { eip712Utils } from '../src/eip712_utils';
-
-import { chaiSetup } from './utils/chai_setup';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('EIP712 Utils', () => {
- describe('createTypedData', () => {
- it('adds in the EIP712DomainSeparator', () => {
- const primaryType = 'Test';
- const typedData = eip712Utils.createTypedData(
- primaryType,
- { Test: [{ name: 'testValue', type: 'uint256' }] },
- { testValue: '1' },
- constants.NULL_ADDRESS,
- );
- expect(typedData.domain).to.not.be.undefined();
- expect(typedData.types.EIP712Domain).to.not.be.undefined();
- const domainObject = typedData.domain;
- expect(domainObject.name).to.eq(constants.EIP712_DOMAIN_NAME);
- expect(typedData.primaryType).to.eq(primaryType);
- });
- });
- describe('createTypedData', () => {
- it('adds in the EIP712DomainSeparator', () => {
- const typedData = eip712Utils.createZeroExTransactionTypedData(
- {
- salt: new BigNumber('0'),
- data: constants.NULL_BYTES,
- signerAddress: constants.NULL_ADDRESS,
- },
- constants.NULL_ADDRESS,
- );
- expect(typedData.primaryType).to.eq(constants.EIP712_ZEROEX_TRANSACTION_SCHEMA.name);
- expect(typedData.types.EIP712Domain).to.not.be.undefined();
- });
- });
-});
diff --git a/packages/order-utils/test/exchange_transfer_simulator_test.ts b/packages/order-utils/test/exchange_transfer_simulator_test.ts
deleted file mode 100644
index c26eb1907..000000000
--- a/packages/order-utils/test/exchange_transfer_simulator_test.ts
+++ /dev/null
@@ -1,174 +0,0 @@
-import { DummyERC20TokenContract, ERC20ProxyContract, ERC20TokenContract } from '@0x/abi-gen-wrappers';
-import * as artifacts from '@0x/contract-artifacts';
-import { BlockchainLifecycle, devConstants } from '@0x/dev-utils';
-import { ExchangeContractErrs } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-
-import { assetDataUtils } from '../src/asset_data_utils';
-import { constants } from '../src/constants';
-import { ExchangeTransferSimulator } from '../src/exchange_transfer_simulator';
-import { BalanceAndProxyAllowanceLazyStore } from '../src/store/balance_and_proxy_allowance_lazy_store';
-import { TradeSide, TransferType } from '../src/types';
-
-import { chaiSetup } from './utils/chai_setup';
-import { SimpleERC20BalanceAndProxyAllowanceFetcher } from './utils/simple_erc20_balance_and_proxy_allowance_fetcher';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-
-describe('ExchangeTransferSimulator', async () => {
- const transferAmount = new BigNumber(5);
- let userAddresses: string[];
- let dummyERC20Token: DummyERC20TokenContract;
- let coinbase: string;
- let sender: string;
- let recipient: string;
- let exampleAssetData: string;
- let exchangeTransferSimulator: ExchangeTransferSimulator;
- let txHash: string;
- let erc20ProxyAddress: string;
- before(async function(): Promise<void> {
- const mochaTestTimeoutMs = 20000;
- this.timeout(mochaTestTimeoutMs); // tslint:disable-line:no-invalid-this
-
- userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- [coinbase, sender, recipient] = userAddresses;
-
- const txDefaults = {
- gas: devConstants.GAS_LIMIT,
- from: devConstants.TESTRPC_FIRST_ADDRESS,
- };
-
- const erc20Proxy = await ERC20ProxyContract.deployFrom0xArtifactAsync(
- artifacts.ERC20Proxy,
- provider,
- txDefaults,
- );
- erc20ProxyAddress = erc20Proxy.address;
-
- const totalSupply = new BigNumber(100000000000000000000);
- const name = 'Test';
- const symbol = 'TST';
- const decimals = new BigNumber(18);
- // tslint:disable-next-line:no-unused-variable
- dummyERC20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
- artifacts.DummyERC20Token,
- provider,
- txDefaults,
- name,
- symbol,
- decimals,
- totalSupply,
- );
-
- exampleAssetData = assetDataUtils.encodeERC20AssetData(dummyERC20Token.address);
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
- describe('#transferFromAsync', function(): void {
- // HACK: For some reason these tests need a slightly longer timeout
- const mochaTestTimeoutMs = 3000;
- this.timeout(mochaTestTimeoutMs); // tslint:disable-line:no-invalid-this
- beforeEach(() => {
- const simpleERC20BalanceAndProxyAllowanceFetcher = new SimpleERC20BalanceAndProxyAllowanceFetcher(
- (dummyERC20Token as any) as ERC20TokenContract,
- erc20ProxyAddress,
- );
- const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
- simpleERC20BalanceAndProxyAllowanceFetcher,
- );
- exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
- });
- it("throws if the user doesn't have enough allowance", async () => {
- return expect(
- exchangeTransferSimulator.transferFromAsync(
- exampleAssetData,
- sender,
- recipient,
- transferAmount,
- TradeSide.Taker,
- TransferType.Trade,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
- });
- it("throws if the user doesn't have enough balance", async () => {
- txHash = await dummyERC20Token.approve.sendTransactionAsync(erc20ProxyAddress, transferAmount, {
- from: sender,
- });
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- return expect(
- exchangeTransferSimulator.transferFromAsync(
- exampleAssetData,
- sender,
- recipient,
- transferAmount,
- TradeSide.Maker,
- TransferType.Trade,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
- });
- it('updates balances and proxyAllowance after transfer', async () => {
- txHash = await dummyERC20Token.transfer.sendTransactionAsync(sender, transferAmount, {
- from: coinbase,
- });
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
-
- txHash = await dummyERC20Token.approve.sendTransactionAsync(erc20ProxyAddress, transferAmount, {
- from: sender,
- });
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
-
- await exchangeTransferSimulator.transferFromAsync(
- exampleAssetData,
- sender,
- recipient,
- transferAmount,
- TradeSide.Taker,
- TransferType.Trade,
- );
- const store = (exchangeTransferSimulator as any)._store;
- const senderBalance = await store.getBalanceAsync(exampleAssetData, sender);
- const recipientBalance = await store.getBalanceAsync(exampleAssetData, recipient);
- const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleAssetData, sender);
- expect(senderBalance).to.be.bignumber.equal(0);
- expect(recipientBalance).to.be.bignumber.equal(transferAmount);
- expect(senderProxyAllowance).to.be.bignumber.equal(0);
- });
- it("doesn't update proxyAllowance after transfer if unlimited", async () => {
- txHash = await dummyERC20Token.transfer.sendTransactionAsync(sender, transferAmount, {
- from: coinbase,
- });
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- txHash = await dummyERC20Token.approve.sendTransactionAsync(
- erc20ProxyAddress,
- constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
- {
- from: sender,
- },
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- await exchangeTransferSimulator.transferFromAsync(
- exampleAssetData,
- sender,
- recipient,
- transferAmount,
- TradeSide.Taker,
- TransferType.Trade,
- );
- const store = (exchangeTransferSimulator as any)._store;
- const senderBalance = await store.getBalanceAsync(exampleAssetData, sender);
- const recipientBalance = await store.getBalanceAsync(exampleAssetData, recipient);
- const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleAssetData, sender);
- expect(senderBalance).to.be.bignumber.equal(0);
- expect(recipientBalance).to.be.bignumber.equal(transferAmount);
- expect(senderProxyAllowance).to.be.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
- });
- });
-});
diff --git a/packages/order-utils/test/market_utils_test.ts b/packages/order-utils/test/market_utils_test.ts
deleted file mode 100644
index 42ea195bb..000000000
--- a/packages/order-utils/test/market_utils_test.ts
+++ /dev/null
@@ -1,267 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import 'mocha';
-
-import { marketUtils } from '../src';
-import { constants } from '../src/constants';
-
-import { chaiSetup } from './utils/chai_setup';
-import { testOrderFactory } from './utils/test_order_factory';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-// tslint:disable: no-unused-expression
-describe('marketUtils', () => {
- describe('#findOrdersThatCoverMakerAssetFillAmount', () => {
- describe('no orders', () => {
- it('returns empty and unchanged remainingFillAmount', async () => {
- const fillAmount = new BigNumber(10);
- const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
- [],
- fillAmount,
- );
- expect(resultOrders).to.be.empty;
- expect(remainingFillAmount).to.be.bignumber.equal(fillAmount);
- });
- });
- describe('orders are completely fillable', () => {
- // generate three signed orders each with 10 units of makerAsset, 30 total
- const makerAssetAmount = new BigNumber(10);
- const inputOrders = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- },
- 3,
- );
- it('returns input orders and zero remainingFillAmount when input exactly matches requested fill amount', async () => {
- // try to fill 20 units of makerAsset
- // include 10 units of slippageBufferAmount
- const fillAmount = new BigNumber(20);
- const slippageBufferAmount = new BigNumber(10);
- const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
- inputOrders,
- fillAmount,
- {
- slippageBufferAmount,
- },
- );
- expect(resultOrders).to.be.deep.equal(inputOrders);
- expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('returns input orders and zero remainingFillAmount when input has more than requested fill amount', async () => {
- // try to fill 15 units of makerAsset
- // include 10 units of slippageBufferAmount
- const fillAmount = new BigNumber(15);
- const slippageBufferAmount = new BigNumber(10);
- const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
- inputOrders,
- fillAmount,
- {
- slippageBufferAmount,
- },
- );
- expect(resultOrders).to.be.deep.equal(inputOrders);
- expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('returns input orders and non-zero remainingFillAmount when input has less than requested fill amount', async () => {
- // try to fill 30 units of makerAsset
- // include 5 units of slippageBufferAmount
- const fillAmount = new BigNumber(30);
- const slippageBufferAmount = new BigNumber(5);
- const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
- inputOrders,
- fillAmount,
- {
- slippageBufferAmount,
- },
- );
- expect(resultOrders).to.be.deep.equal(inputOrders);
- expect(remainingFillAmount).to.be.bignumber.equal(new BigNumber(5));
- });
- it('returns first order and zero remainingFillAmount when requested fill amount is exactly covered by the first order', async () => {
- // try to fill 10 units of makerAsset
- const fillAmount = new BigNumber(10);
- const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
- inputOrders,
- fillAmount,
- );
- expect(resultOrders).to.be.deep.equal([inputOrders[0]]);
- expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('returns first two orders and zero remainingFillAmount when requested fill amount is over covered by the first two order', async () => {
- // try to fill 15 units of makerAsset
- const fillAmount = new BigNumber(15);
- const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
- inputOrders,
- fillAmount,
- );
- expect(resultOrders).to.be.deep.equal([inputOrders[0], inputOrders[1]]);
- expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- });
- describe('orders are partially fillable', () => {
- // generate three signed orders each with 10 units of makerAsset, 30 total
- const makerAssetAmount = new BigNumber(10);
- const inputOrders = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- },
- 3,
- );
- // generate remainingFillableMakerAssetAmounts that cover different partial fill scenarios
- // 1. order is completely filled already
- // 2. order is partially fillable
- // 3. order is completely fillable
- const remainingFillableMakerAssetAmounts = [constants.ZERO_AMOUNT, new BigNumber(5), makerAssetAmount];
- it('returns last two orders and non-zero remainingFillAmount when trying to fill original makerAssetAmounts', async () => {
- // try to fill 30 units of makerAsset
- const fillAmount = new BigNumber(30);
- const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
- inputOrders,
- fillAmount,
- {
- remainingFillableMakerAssetAmounts,
- },
- );
- expect(resultOrders).to.be.deep.equal([inputOrders[1], inputOrders[2]]);
- expect(remainingFillAmount).to.be.bignumber.equal(new BigNumber(15));
- });
- });
- });
- describe('#findFeeOrdersThatCoverFeesForTargetOrders', () => {
- // generate three signed fee orders each with 10 units of ZRX, 30 total
- const zrxAmount = new BigNumber(10);
- const inputFeeOrders = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount: zrxAmount,
- },
- 3,
- );
- describe('no target orders', () => {
- it('returns empty and zero remainingFeeAmount', async () => {
- const { resultFeeOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
- [],
- inputFeeOrders,
- );
- expect(resultFeeOrders).to.be.empty;
- expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- });
- describe('no fee orders', () => {
- // generate three signed orders each with 10 units of makerAsset, 30 total
- // each signed order requires 10 units of takerFee
- const makerAssetAmount = new BigNumber(10);
- const takerFee = new BigNumber(10);
- const inputOrders = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerFee,
- },
- 3,
- );
- // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount
- const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount];
- it('returns empty and non-zero remainingFeeAmount', async () => {
- const { resultFeeOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
- inputOrders,
- [],
- {
- remainingFillableMakerAssetAmounts,
- },
- );
- expect(resultFeeOrders).to.be.empty;
- expect(remainingFeeAmount).to.be.bignumber.equal(new BigNumber(30));
- });
- });
- describe('target orders have no fees', () => {
- // generate three signed orders each with 10 units of makerAsset, 30 total
- const makerAssetAmount = new BigNumber(10);
- const inputOrders = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- },
- 3,
- );
- it('returns empty and zero remainingFeeAmount', async () => {
- const { resultFeeOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
- inputOrders,
- inputFeeOrders,
- );
- expect(resultFeeOrders).to.be.empty;
- expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- });
- describe('target orders require fees and are completely fillable', () => {
- // generate three signed orders each with 10 units of makerAsset, 30 total
- // each signed order requires 10 units of takerFee
- const makerAssetAmount = new BigNumber(10);
- const takerFee = new BigNumber(10);
- const inputOrders = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerFee,
- },
- 3,
- );
- it('returns input fee orders and zero remainingFeeAmount', async () => {
- const { resultFeeOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
- inputOrders,
- inputFeeOrders,
- );
- expect(resultFeeOrders).to.be.deep.equal(inputFeeOrders);
- expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- });
- describe('target orders require fees and are partially fillable', () => {
- // generate three signed orders each with 10 units of makerAsset, 30 total
- // each signed order requires 10 units of takerFee
- const makerAssetAmount = new BigNumber(10);
- const takerFee = new BigNumber(10);
- const inputOrders = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerFee,
- },
- 3,
- );
- // generate remainingFillableMakerAssetAmounts that cover different partial fill scenarios
- // 1. order is completely filled already
- // 2. order is partially fillable
- // 3. order is completely fillable
- const remainingFillableMakerAssetAmounts = [constants.ZERO_AMOUNT, new BigNumber(5), makerAssetAmount];
- it('returns first two input fee orders and zero remainingFeeAmount', async () => {
- const { resultFeeOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
- inputOrders,
- inputFeeOrders,
- {
- remainingFillableMakerAssetAmounts,
- },
- );
- expect(resultFeeOrders).to.be.deep.equal([inputFeeOrders[0], inputFeeOrders[1]]);
- expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- });
- describe('target orders require more fees than available', () => {
- // generate three signed orders each with 10 units of makerAsset, 30 total
- // each signed order requires 20 units of takerFee
- const makerAssetAmount = new BigNumber(10);
- const takerFee = new BigNumber(20);
- const inputOrders = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerFee,
- },
- 3,
- );
- it('returns input fee orders and non-zero remainingFeeAmount', async () => {
- const { resultFeeOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
- inputOrders,
- inputFeeOrders,
- );
- expect(resultFeeOrders).to.be.deep.equal(inputFeeOrders);
- expect(remainingFeeAmount).to.be.bignumber.equal(new BigNumber(30));
- });
- });
- });
-});
diff --git a/packages/order-utils/test/order_hash_test.ts b/packages/order-utils/test/order_hash_test.ts
deleted file mode 100644
index 30fb15a37..000000000
--- a/packages/order-utils/test/order_hash_test.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { Order } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import 'mocha';
-
-import { orderHashUtils } from '../src';
-
-import { constants } from '../src/constants';
-
-import { chaiSetup } from './utils/chai_setup';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('Order hashing', () => {
- describe('#getOrderHashHex', () => {
- const expectedOrderHash = '0x434c6b41e2fb6dfcfe1b45c4492fb03700798e9c1afc6f801ba6203f948c1fa7';
- const fakeExchangeContractAddress = '0x1dc4c1cefef38a777b15aa20260a54e584b16c48';
- const order: Order = {
- makerAddress: constants.NULL_ADDRESS,
- takerAddress: constants.NULL_ADDRESS,
- senderAddress: constants.NULL_ADDRESS,
- feeRecipientAddress: constants.NULL_ADDRESS,
- makerAssetData: constants.NULL_ADDRESS,
- takerAssetData: constants.NULL_ADDRESS,
- exchangeAddress: fakeExchangeContractAddress,
- salt: new BigNumber(0),
- makerFee: new BigNumber(0),
- takerFee: new BigNumber(0),
- makerAssetAmount: new BigNumber(0),
- takerAssetAmount: new BigNumber(0),
- expirationTimeSeconds: new BigNumber(0),
- };
- it('calculates the order hash', async () => {
- const orderHash = orderHashUtils.getOrderHashHex(order);
- expect(orderHash).to.be.equal(expectedOrderHash);
- });
- it('calculates the order hash if amounts are strings', async () => {
- // It's common for developers using javascript to provide the amounts
- // as strings. Since we eventually toString() the BigNumber
- // before encoding we should result in the same orderHash in this scenario
- // tslint:disable-next-line:no-unnecessary-type-assertion
- const orderHash = orderHashUtils.getOrderHashHex({
- ...order,
- makerAssetAmount: '0',
- takerAssetAmount: '0',
- makerFee: '0',
- takerFee: '0',
- } as any);
- expect(orderHash).to.be.equal(expectedOrderHash);
- });
- it('throws a readable error message if taker format is invalid', async () => {
- const orderWithInvalidtakerFormat = {
- ...order,
- takerAddress: (null as any) as string,
- };
- const expectedErrorMessage =
- 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
- expect(() => orderHashUtils.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
- });
- });
- describe('#isValidOrderHash', () => {
- it('returns false if the value is not a hex string', () => {
- const isValid = orderHashUtils.isValidOrderHash('not a hex');
- expect(isValid).to.be.false();
- });
- it('returns false if the length is wrong', () => {
- const isValid = orderHashUtils.isValidOrderHash('0xdeadbeef');
- expect(isValid).to.be.false();
- });
- it('returns true if order hash is correct', () => {
- const orderHashLength = 65;
- const isValid = orderHashUtils.isValidOrderHash(`0x${Array(orderHashLength).join('0')}`);
- expect(isValid).to.be.true();
- });
- });
-});
diff --git a/packages/order-utils/test/order_state_utils_test.ts b/packages/order-utils/test/order_state_utils_test.ts
deleted file mode 100644
index 42acd54c6..000000000
--- a/packages/order-utils/test/order_state_utils_test.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-import { SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import 'mocha';
-
-import { AbstractBalanceAndProxyAllowanceFetcher } from '../src/abstract/abstract_balance_and_proxy_allowance_fetcher';
-import { AbstractOrderFilledCancelledFetcher } from '../src/abstract/abstract_order_filled_cancelled_fetcher';
-import { OrderStateUtils } from '../src/order_state_utils';
-
-import { chaiSetup } from './utils/chai_setup';
-import { testOrderFactory } from './utils/test_order_factory';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('OrderStateUtils', () => {
- describe('#getOpenOrderStateAsync', () => {
- const buildMockBalanceFetcher = (takerBalance: BigNumber): AbstractBalanceAndProxyAllowanceFetcher => {
- const balanceFetcher = {
- async getBalanceAsync(_assetData: string, _userAddress: string): Promise<BigNumber> {
- return takerBalance;
- },
- async getProxyAllowanceAsync(_assetData: string, _userAddress: string): Promise<BigNumber> {
- return takerBalance;
- },
- };
- return balanceFetcher;
- };
- const buildMockOrderFilledFetcher = (
- filledAmount: BigNumber = new BigNumber(0),
- cancelled: boolean = false,
- ): AbstractOrderFilledCancelledFetcher => {
- const orderFetcher = {
- async getFilledTakerAmountAsync(_orderHash: string): Promise<BigNumber> {
- return filledAmount;
- },
- async isOrderCancelledAsync(_signedOrder: SignedOrder): Promise<boolean> {
- return cancelled;
- },
- getZRXAssetData(): string {
- return '';
- },
- };
- return orderFetcher;
- };
- it('should have valid order state if order can be fully filled with small maker amount', async () => {
- const makerAssetAmount = new BigNumber(10);
- const takerAssetAmount = new BigNumber(10000000000000000);
- const takerBalance = takerAssetAmount;
- const orderFilledAmount = new BigNumber(0);
- const mockBalanceFetcher = buildMockBalanceFetcher(takerBalance);
- const mockOrderFilledFetcher = buildMockOrderFilledFetcher(orderFilledAmount);
- const [signedOrder] = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerAssetAmount,
- },
- 1,
- );
-
- const orderStateUtils = new OrderStateUtils(mockBalanceFetcher, mockOrderFilledFetcher);
- const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder);
- expect(orderState.isValid).to.eq(true);
- });
- it('should be invalid when an order is partially filled where only a rounding error remains', async () => {
- const makerAssetAmount = new BigNumber(1001);
- const takerAssetAmount = new BigNumber(3);
- const takerBalance = takerAssetAmount;
- const orderFilledAmount = new BigNumber(2);
- const mockBalanceFetcher = buildMockBalanceFetcher(takerBalance);
- const mockOrderFilledFetcher = buildMockOrderFilledFetcher(orderFilledAmount);
- const [signedOrder] = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerAssetAmount,
- },
- 1,
- );
-
- const orderStateUtils = new OrderStateUtils(mockBalanceFetcher, mockOrderFilledFetcher);
- const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder);
- expect(orderState.isValid).to.eq(false);
- });
- it('should be invalid when an order is cancelled', async () => {
- const makerAssetAmount = new BigNumber(1000);
- const takerAssetAmount = new BigNumber(2);
- const takerBalance = takerAssetAmount;
- const orderFilledAmount = new BigNumber(0);
- const isCancelled = true;
- const mockBalanceFetcher = buildMockBalanceFetcher(takerBalance);
- const mockOrderFilledFetcher = buildMockOrderFilledFetcher(orderFilledAmount, isCancelled);
- const [signedOrder] = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerAssetAmount,
- },
- 1,
- );
-
- const orderStateUtils = new OrderStateUtils(mockBalanceFetcher, mockOrderFilledFetcher);
- const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder);
- expect(orderState.isValid).to.eq(false);
- });
- it('should be invalid when an order is fully filled', async () => {
- const makerAssetAmount = new BigNumber(1000);
- const takerAssetAmount = new BigNumber(2);
- const takerBalance = takerAssetAmount;
- const orderFilledAmount = takerAssetAmount;
- const isCancelled = false;
- const mockBalanceFetcher = buildMockBalanceFetcher(takerBalance);
- const mockOrderFilledFetcher = buildMockOrderFilledFetcher(orderFilledAmount, isCancelled);
- const [signedOrder] = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerAssetAmount,
- },
- 1,
- );
-
- const orderStateUtils = new OrderStateUtils(mockBalanceFetcher, mockOrderFilledFetcher);
- const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder);
- expect(orderState.isValid).to.eq(false);
- });
- it('should include the transactionHash in orderState if supplied in method invocation', async () => {
- const makerAssetAmount = new BigNumber(10);
- const takerAssetAmount = new BigNumber(10000000000000000);
- const takerBalance = takerAssetAmount;
- const orderFilledAmount = new BigNumber(0);
- const mockBalanceFetcher = buildMockBalanceFetcher(takerBalance);
- const mockOrderFilledFetcher = buildMockOrderFilledFetcher(orderFilledAmount);
- const [signedOrder] = testOrderFactory.generateTestSignedOrders(
- {
- makerAssetAmount,
- takerAssetAmount,
- },
- 1,
- );
-
- const orderStateUtils = new OrderStateUtils(mockBalanceFetcher, mockOrderFilledFetcher);
- const transactionHash = '0xdeadbeef';
- const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder, transactionHash);
- expect(orderState.transactionHash).to.eq(transactionHash);
- });
- });
-});
diff --git a/packages/order-utils/test/order_validation_utils_test.ts b/packages/order-utils/test/order_validation_utils_test.ts
deleted file mode 100644
index d4d12a6a7..000000000
--- a/packages/order-utils/test/order_validation_utils_test.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import 'mocha';
-
-import { OrderValidationUtils } from '../src/order_validation_utils';
-
-import { chaiSetup } from './utils/chai_setup';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('OrderValidationUtils', () => {
- describe('#isRoundingError', () => {
- it('should return false if there is a rounding error of 0.1%', async () => {
- const numerator = new BigNumber(20);
- const denominator = new BigNumber(999);
- const target = new BigNumber(50);
- // rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1%
- const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
- expect(isRoundingError).to.be.false();
- });
-
- it('should return false if there is a rounding of 0.09%', async () => {
- const numerator = new BigNumber(20);
- const denominator = new BigNumber(9991);
- const target = new BigNumber(500);
- // rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09%
- const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
- expect(isRoundingError).to.be.false();
- });
-
- it('should return true if there is a rounding error of 0.11%', async () => {
- const numerator = new BigNumber(20);
- const denominator = new BigNumber(9989);
- const target = new BigNumber(500);
- // rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011%
- const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
- expect(isRoundingError).to.be.true();
- });
-
- it('should return true if there is a rounding error > 0.1%', async () => {
- const numerator = new BigNumber(3);
- const denominator = new BigNumber(7);
- const target = new BigNumber(10);
- // rounding error = ((3*10/7) - floor(3*10/7)) / (3*10/7) = 6.67%
- const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
- expect(isRoundingError).to.be.true();
- });
-
- it('should return false when there is no rounding error', async () => {
- const numerator = new BigNumber(1);
- const denominator = new BigNumber(2);
- const target = new BigNumber(10);
-
- const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
- expect(isRoundingError).to.be.false();
- });
-
- it('should return false when there is rounding error <= 0.1%', async () => {
- // randomly generated numbers
- const numerator = new BigNumber(76564);
- const denominator = new BigNumber(676373677);
- const target = new BigNumber(105762562);
- // rounding error = ((76564*105762562/676373677) - floor(76564*105762562/676373677)) /
- // (76564*105762562/676373677) = 0.0007%
- const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
- expect(isRoundingError).to.be.false();
- });
- });
-});
diff --git a/packages/order-utils/test/rate_utils_test.ts b/packages/order-utils/test/rate_utils_test.ts
deleted file mode 100644
index b13878bb5..000000000
--- a/packages/order-utils/test/rate_utils_test.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import 'mocha';
-
-import { rateUtils } from '../src';
-
-import { chaiSetup } from './utils/chai_setup';
-import { testOrderFactory } from './utils/test_order_factory';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('rateUtils', () => {
- const testOrder = testOrderFactory.generateTestSignedOrder({
- makerAssetAmount: new BigNumber(100),
- takerAssetAmount: new BigNumber(100),
- takerFee: new BigNumber(20),
- });
- describe('#getFeeAdjustedRateOfOrder', () => {
- it('throws when feeRate is less than zero', async () => {
- const feeRate = new BigNumber(-1);
- expect(() => rateUtils.getFeeAdjustedRateOfOrder(testOrder, feeRate)).to.throw(
- 'Expected feeRate: -1 to be greater than or equal to 0',
- );
- });
- it('correctly calculates fee adjusted rate when feeRate is provided', async () => {
- const feeRate = new BigNumber(2); // ZRX costs 2 units of takerAsset per 1 unit of ZRX
- const feeAdjustedRate = rateUtils.getFeeAdjustedRateOfOrder(testOrder, feeRate);
- // the order actually takes 100 + (2 * 20) takerAsset units to fill 100 units of makerAsset
- expect(feeAdjustedRate).to.bignumber.equal(new BigNumber(1.4));
- });
- it('correctly calculates fee adjusted rate when no feeRate is provided', async () => {
- const feeAdjustedRate = rateUtils.getFeeAdjustedRateOfOrder(testOrder);
- // because no feeRate was provided we just assume 0 fees
- // the order actually takes 100 takerAsset units to fill 100 units of makerAsset
- expect(feeAdjustedRate).to.bignumber.equal(new BigNumber(1));
- });
- });
- describe('#getFeeAdjustedRateOfFeeOrder', () => {
- it('throws when takerFee exceeds makerAssetAmount', async () => {
- const badOrder = testOrderFactory.generateTestSignedOrder({
- makerAssetAmount: new BigNumber(100),
- takerFee: new BigNumber(101),
- });
- expect(() => rateUtils.getFeeAdjustedRateOfFeeOrder(badOrder)).to.throw(
- 'Expected takerFee: "101" to be less than makerAssetAmount: "100"',
- );
- });
- it('correctly calculates fee adjusted rate', async () => {
- const feeAdjustedRate = rateUtils.getFeeAdjustedRateOfFeeOrder(testOrder);
- // the order actually takes 100 takerAsset units to fill (100 - 20) units of makerAsset
- expect(feeAdjustedRate).to.bignumber.equal(new BigNumber(1.25));
- });
- });
-});
diff --git a/packages/order-utils/test/remaining_fillable_calculator_test.ts b/packages/order-utils/test/remaining_fillable_calculator_test.ts
deleted file mode 100644
index affad8f1c..000000000
--- a/packages/order-utils/test/remaining_fillable_calculator_test.ts
+++ /dev/null
@@ -1,246 +0,0 @@
-import { SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as chai from 'chai';
-import 'mocha';
-
-import { RemainingFillableCalculator } from '../src/remaining_fillable_calculator';
-
-import { chaiSetup } from './utils/chai_setup';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('RemainingFillableCalculator', () => {
- let calculator: RemainingFillableCalculator;
- let signedOrder: SignedOrder;
- let transferrableMakeAssetAmount: BigNumber;
- let transferrableMakerFeeTokenAmount: BigNumber;
- let remainingMakeAssetAmount: BigNumber;
- let makerAmount: BigNumber;
- let takerAmount: BigNumber;
- let makerFeeAmount: BigNumber;
- let isMakeAssetZRX: boolean;
- const makerAssetData: string = '0x1';
- const takerAssetData: string = '0x2';
- const decimals: number = 4;
- const zero: BigNumber = new BigNumber(0);
- const zeroAddress = '0x0';
- const signature: string =
- '0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403';
- beforeEach(async () => {
- [makerAmount, takerAmount, makerFeeAmount] = [
- Web3Wrapper.toBaseUnitAmount(new BigNumber(50), decimals),
- Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals),
- Web3Wrapper.toBaseUnitAmount(new BigNumber(1), decimals),
- ];
- [transferrableMakeAssetAmount, transferrableMakerFeeTokenAmount] = [
- Web3Wrapper.toBaseUnitAmount(new BigNumber(50), decimals),
- Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals),
- ];
- });
- function buildSignedOrder(): SignedOrder {
- return {
- signature,
- exchangeAddress: zeroAddress,
- feeRecipientAddress: zeroAddress,
- senderAddress: zeroAddress,
- makerAddress: zeroAddress,
- takerAddress: zeroAddress,
- makerFee: makerFeeAmount,
- takerFee: zero,
- makerAssetAmount: makerAmount,
- takerAssetAmount: takerAmount,
- makerAssetData,
- takerAssetData,
- salt: zero,
- expirationTimeSeconds: zero,
- };
- }
- describe('Maker token is NOT ZRX', () => {
- before(async () => {
- isMakeAssetZRX = false;
- });
- it('calculates the correct amount when unfilled and funds available', () => {
- signedOrder = buildSignedOrder();
- remainingMakeAssetAmount = signedOrder.makerAssetAmount;
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(remainingMakeAssetAmount);
- });
- it('calculates the correct amount when partially filled and funds available', () => {
- signedOrder = buildSignedOrder();
- remainingMakeAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1), decimals);
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(remainingMakeAssetAmount);
- });
- it('calculates the amount to be 0 when all fee funds are transferred', () => {
- signedOrder = buildSignedOrder();
- transferrableMakerFeeTokenAmount = zero;
- remainingMakeAssetAmount = signedOrder.makerAssetAmount;
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(zero);
- });
- it('calculates the correct amount when balance is less than remaining fillable', () => {
- signedOrder = buildSignedOrder();
- const partiallyFilledAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
- remainingMakeAssetAmount = signedOrder.makerAssetAmount.minus(partiallyFilledAmount);
- transferrableMakeAssetAmount = remainingMakeAssetAmount.minus(partiallyFilledAmount);
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(transferrableMakeAssetAmount);
- });
- describe('Order to Fee Ratio is < 1', () => {
- beforeEach(async () => {
- [makerAmount, takerAmount, makerFeeAmount] = [
- Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals),
- Web3Wrapper.toBaseUnitAmount(new BigNumber(6), decimals),
- Web3Wrapper.toBaseUnitAmount(new BigNumber(6), decimals),
- ];
- });
- it('calculates the correct amount when funds unavailable', () => {
- signedOrder = buildSignedOrder();
- remainingMakeAssetAmount = signedOrder.makerAssetAmount;
- const transferredAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
- transferrableMakeAssetAmount = remainingMakeAssetAmount.minus(transferredAmount);
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(transferrableMakeAssetAmount);
- });
- });
- describe('Ratio is not evenly divisble', () => {
- beforeEach(async () => {
- [makerAmount, takerAmount, makerFeeAmount] = [
- Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals),
- Web3Wrapper.toBaseUnitAmount(new BigNumber(7), decimals),
- Web3Wrapper.toBaseUnitAmount(new BigNumber(7), decimals),
- ];
- });
- it('calculates the correct amount when funds unavailable', () => {
- signedOrder = buildSignedOrder();
- remainingMakeAssetAmount = signedOrder.makerAssetAmount;
- const transferredAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
- transferrableMakeAssetAmount = remainingMakeAssetAmount.minus(transferredAmount);
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- const calculatedFillableAmount = calculator.computeRemainingFillable();
- expect(calculatedFillableAmount.isLessThanOrEqualTo(transferrableMakeAssetAmount)).to.be.true();
- expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
- const orderToFeeRatio = signedOrder.makerAssetAmount.dividedBy(signedOrder.makerFee);
- const calculatedFeeAmount = calculatedFillableAmount.dividedBy(orderToFeeRatio);
- expect(calculatedFeeAmount).to.be.bignumber.lessThan(transferrableMakerFeeTokenAmount);
- });
- });
- });
- describe('Maker Token is ZRX', () => {
- before(async () => {
- isMakeAssetZRX = true;
- });
- it('calculates the correct amount when unfilled and funds available', () => {
- signedOrder = buildSignedOrder();
- transferrableMakeAssetAmount = makerAmount.plus(makerFeeAmount);
- transferrableMakerFeeTokenAmount = transferrableMakeAssetAmount;
- remainingMakeAssetAmount = signedOrder.makerAssetAmount;
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(remainingMakeAssetAmount);
- });
- it('calculates the correct amount when partially filled and funds available', () => {
- signedOrder = buildSignedOrder();
- remainingMakeAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1), decimals);
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(remainingMakeAssetAmount);
- });
- it('calculates the amount to be 0 when all fee funds are transferred', () => {
- signedOrder = buildSignedOrder();
- transferrableMakeAssetAmount = zero;
- transferrableMakerFeeTokenAmount = zero;
- remainingMakeAssetAmount = signedOrder.makerAssetAmount;
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(zero);
- });
- it('calculates the correct amount when balance is less than remaining fillable', () => {
- signedOrder = buildSignedOrder();
- const partiallyFilledAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
- remainingMakeAssetAmount = signedOrder.makerAssetAmount.minus(partiallyFilledAmount);
- transferrableMakeAssetAmount = remainingMakeAssetAmount.minus(partiallyFilledAmount);
- transferrableMakerFeeTokenAmount = transferrableMakeAssetAmount;
-
- const orderToFeeRatio = signedOrder.makerAssetAmount.dividedToIntegerBy(signedOrder.makerFee);
- const expectedFillableAmount = new BigNumber(450980);
- calculator = new RemainingFillableCalculator(
- signedOrder.makerFee,
- signedOrder.makerAssetAmount,
- isMakeAssetZRX,
- transferrableMakeAssetAmount,
- transferrableMakerFeeTokenAmount,
- remainingMakeAssetAmount,
- );
- const calculatedFillableAmount = calculator.computeRemainingFillable();
- const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
- const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
- expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(transferrableMakeAssetAmount);
- expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(remainingMakeAssetAmount);
- expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount);
- expect(numberOfFillsInRatio.decimalPlaces()).to.be.equal(0);
- });
- });
-});
diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts
deleted file mode 100644
index 937382056..000000000
--- a/packages/order-utils/test/signature_utils_test.ts
+++ /dev/null
@@ -1,324 +0,0 @@
-import { Order, SignatureType } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import { JSONRPCErrorCallback, JSONRPCRequestPayload } from 'ethereum-types';
-import * as ethUtil from 'ethereumjs-util';
-import * as _ from 'lodash';
-import 'mocha';
-
-import { generatePseudoRandomSalt, orderHashUtils } from '../src';
-import { constants } from '../src/constants';
-import { signatureUtils } from '../src/signature_utils';
-
-import { chaiSetup } from './utils/chai_setup';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('Signature utils', () => {
- let makerAddress: string;
- const fakeExchangeContractAddress = '0x1dc4c1cefef38a777b15aa20260a54e584b16c48';
- let order: Order;
- before(async () => {
- const availableAddreses = await web3Wrapper.getAvailableAddressesAsync();
- makerAddress = availableAddreses[0];
- order = {
- makerAddress,
- takerAddress: constants.NULL_ADDRESS,
- senderAddress: constants.NULL_ADDRESS,
- feeRecipientAddress: constants.NULL_ADDRESS,
- makerAssetData: constants.NULL_ADDRESS,
- takerAssetData: constants.NULL_ADDRESS,
- exchangeAddress: fakeExchangeContractAddress,
- salt: new BigNumber(0),
- makerFee: new BigNumber(0),
- takerFee: new BigNumber(0),
- makerAssetAmount: new BigNumber(0),
- takerAssetAmount: new BigNumber(0),
- expirationTimeSeconds: new BigNumber(0),
- };
- });
- describe('#isValidSignatureAsync', () => {
- let dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
- const ethSignSignature =
- '0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403';
- let address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
-
- it("should return false if the data doesn't pertain to the signature & address", async () => {
- const bytes32Zeros = '0x0000000000000000000000000000000000000000000000000000000000000000';
- expect(
- await signatureUtils.isValidSignatureAsync(provider, bytes32Zeros, ethSignSignature, address),
- ).to.be.false();
- });
- it("should return false if the address doesn't pertain to the signature & data", async () => {
- const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
- expect(
- await signatureUtils.isValidSignatureAsync(provider, dataHex, ethSignSignature, validUnrelatedAddress),
- ).to.be.false();
- });
- it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
- const signatureArray = ethSignSignature.split('');
- // tslint:disable-next-line:custom-no-magic-numbers
- signatureArray[5] = 'C'; // V = 28, instead of 27
- const wrongSignature = signatureArray.join('');
- expect(
- await signatureUtils.isValidSignatureAsync(provider, dataHex, wrongSignature, address),
- ).to.be.false();
- });
-
- it('should throw if signatureType is invalid', () => {
- const signatureArray = ethSignSignature.split('');
- signatureArray[3] = '9'; // SignatureType w/ index 9 doesn't exist
- const signatureWithInvalidType = signatureArray.join('');
- expect(
- signatureUtils.isValidSignatureAsync(provider, dataHex, signatureWithInvalidType, address),
- ).to.be.rejected();
- });
-
- it('should return true for a valid Ecrecover (EthSign) signature', async () => {
- const isValidSignatureLocal = await signatureUtils.isValidSignatureAsync(
- provider,
- dataHex,
- ethSignSignature,
- address,
- );
- expect(isValidSignatureLocal).to.be.true();
- });
-
- it('should return true for a valid EIP712 signature', async () => {
- dataHex = '0xa1d7403bcbbcd75ec233cfd6584ff8dabed677d0e9bb32c2bea94e9dd8a109da';
- address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb';
- const eip712Signature =
- '0x1bdde07aac4bf12c12ddbb155919c43eba4146a2cfcf904a862950dbebe332554c6674975603eb5a4eaf8fd7f2e06350267e5b36cda9851a89f8bb49fe2fc9afe202';
- const isValidSignatureLocal = await signatureUtils.isValidSignatureAsync(
- provider,
- dataHex,
- eip712Signature,
- address,
- );
- expect(isValidSignatureLocal).to.be.true();
- });
- });
- describe('#isValidECSignature', () => {
- const signature = {
- v: 27,
- r: '0xaca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d64393',
- s: '0x46b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf2',
- };
- const data = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad';
- const address = '0x0e5cb767cce09a7f3ca594df118aa519be5e2b5a';
-
- it("should return false if the data doesn't pertain to the signature & address", async () => {
- expect(signatureUtils.isValidECSignature('0x0', signature, address)).to.be.false();
- });
- it("should return false if the address doesn't pertain to the signature & data", async () => {
- const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
- expect(signatureUtils.isValidECSignature(data, signature, validUnrelatedAddress)).to.be.false();
- });
- it("should return false if the signature doesn't pertain to the data & address", async () => {
- const wrongSignature = _.assign({}, signature, { v: 28 });
- expect(signatureUtils.isValidECSignature(data, wrongSignature, address)).to.be.false();
- });
- it('should return true if the signature does pertain to the data & address', async () => {
- const isValidSignatureLocal = signatureUtils.isValidECSignature(data, signature, address);
- expect(isValidSignatureLocal).to.be.true();
- });
- });
- describe('#generateSalt', () => {
- it('generates different salts', () => {
- const isEqual = generatePseudoRandomSalt().eq(generatePseudoRandomSalt());
- expect(isEqual).to.be.false();
- });
- it('generates salt in range [0..2^256)', () => {
- const salt = generatePseudoRandomSalt();
- expect(salt.isGreaterThanOrEqualTo(0)).to.be.true();
- // tslint:disable-next-line:custom-no-magic-numbers
- const twoPow256 = new BigNumber(2).pow(256);
- expect(salt.isLessThan(twoPow256)).to.be.true();
- });
- });
- describe('#ecSignOrderAsync', () => {
- it('should default to eth_sign if eth_signTypedData is unavailable', async () => {
- const expectedSignature =
- '0x1c3582f06356a1314dbf1c0e534c4d8e92e59b056ee607a7ff5a825f5f2cc5e6151c5cc7fdd420f5608e4d5bef108e42ad90c7a4b408caef32e24374cf387b0d7603';
-
- const fakeProvider = {
- async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
- if (payload.method === 'eth_signTypedData') {
- callback(new Error('Internal RPC Error'));
- } else if (payload.method === 'eth_sign') {
- const [address, message] = payload.params;
- const signature = await web3Wrapper.signMessageAsync(address, message);
- callback(null, {
- id: 42,
- jsonrpc: '2.0',
- result: signature,
- });
- } else {
- callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] });
- }
- },
- };
- const signedOrder = await signatureUtils.ecSignOrderAsync(fakeProvider, order, makerAddress);
- expect(signedOrder.signature).to.equal(expectedSignature);
- });
- it('should throw if the user denies the signing request', async () => {
- const fakeProvider = {
- async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
- if (payload.method === 'eth_signTypedData') {
- callback(new Error('User denied message signature'));
- } else if (payload.method === 'eth_sign') {
- const [address, message] = payload.params;
- const signature = await web3Wrapper.signMessageAsync(address, message);
- callback(null, {
- id: 42,
- jsonrpc: '2.0',
- result: signature,
- });
- } else {
- callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] });
- }
- },
- };
- expect(signatureUtils.ecSignOrderAsync(fakeProvider, order, makerAddress)).to.to.be.rejectedWith(
- 'User denied message signature',
- );
- });
- });
- describe('#ecSignHashAsync', () => {
- before(async () => {
- const availableAddreses = await web3Wrapper.getAvailableAddressesAsync();
- makerAddress = availableAddreses[0];
- });
- it('should return the correct Signature', async () => {
- const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
- const expectedSignature =
- '0x1b61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403';
- const ecSignature = await signatureUtils.ecSignHashAsync(provider, orderHash, makerAddress);
- expect(ecSignature).to.equal(expectedSignature);
- });
- it('should return the correct Signature for signatureHex concatenated as R + S + V', async () => {
- const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
- const expectedSignature =
- '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03';
-
- const fakeProvider = {
- async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
- if (payload.method === 'eth_sign') {
- const [address, message] = payload.params;
- expect(message).to.equal(orderHash);
- const signature = await web3Wrapper.signMessageAsync(address, message);
- // tslint:disable-next-line:custom-no-magic-numbers
- const rsvHex = `0x${signature.substr(130)}${signature.substr(2, 128)}`;
- callback(null, {
- id: 42,
- jsonrpc: '2.0',
- result: rsvHex,
- });
- } else {
- callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] });
- }
- },
- };
- const ecSignature = await signatureUtils.ecSignHashAsync(fakeProvider, orderHash, makerAddress);
- expect(ecSignature).to.equal(expectedSignature);
- });
- it('should return the correct Signature for signatureHex concatenated as V + R + S', async () => {
- const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
- const expectedSignature =
- '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03';
- const fakeProvider = {
- async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
- if (payload.method === 'eth_sign') {
- const [address, message] = payload.params;
- const signature = await web3Wrapper.signMessageAsync(address, message);
- callback(null, {
- id: 42,
- jsonrpc: '2.0',
- result: signature,
- });
- } else {
- callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] });
- }
- },
- };
-
- const ecSignature = await signatureUtils.ecSignHashAsync(fakeProvider, orderHash, makerAddress);
- expect(ecSignature).to.equal(expectedSignature);
- });
- it('should return a valid signature', async () => {
- const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
- const ecSignature = await signatureUtils.ecSignHashAsync(provider, orderHash, makerAddress);
-
- const isValidSignature = await signatureUtils.isValidSignatureAsync(
- provider,
- orderHash,
- ecSignature,
- makerAddress,
- );
- expect(isValidSignature).to.be.true();
- });
- });
- describe('#ecSignTypedDataOrderAsync', () => {
- it('should result in the same signature as signing the order hash without an ethereum message prefix', async () => {
- // Note: Since order hash is an EIP712 hash the result of a valid EIP712 signature
- // of order hash is the same as signing the order without the Ethereum Message prefix.
- const orderHashHex = orderHashUtils.getOrderHashHex(order);
- const sig = ethUtil.ecsign(
- ethUtil.toBuffer(orderHashHex),
- Buffer.from('F2F48EE19680706196E2E339E5DA3491186E0C4C5030670656B0E0164837257D', 'hex'),
- );
- const signatureBuffer = Buffer.concat([
- ethUtil.toBuffer(sig.v),
- ethUtil.toBuffer(sig.r),
- ethUtil.toBuffer(sig.s),
- ethUtil.toBuffer(SignatureType.EIP712),
- ]);
- const signatureHex = `0x${signatureBuffer.toString('hex')}`;
- const signedOrder = await signatureUtils.ecSignTypedDataOrderAsync(provider, order, makerAddress);
- const isValidSignature = await signatureUtils.isValidSignatureAsync(
- provider,
- orderHashHex,
- signedOrder.signature,
- makerAddress,
- );
- expect(signatureHex).to.eq(signedOrder.signature);
- expect(isValidSignature).to.eq(true);
- });
- it('should return the correct Signature for signatureHex concatenated as R + S + V', async () => {
- const expectedSignature =
- '0x1cd472c439833774b55d248c31b6585f21aea1b9363ebb4ec58549e46b62eb5a6f696f5781f62de008ee7f77650ef940d99c97ec1dee67b3f5cea1bbfdfeb2eba602';
- const fakeProvider = {
- async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
- if (payload.method === 'eth_signTypedData') {
- const [address, typedData] = payload.params;
- const signature = await web3Wrapper.signTypedDataAsync(address, typedData);
- callback(null, {
- id: 42,
- jsonrpc: '2.0',
- result: signature,
- });
- } else {
- callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] });
- }
- },
- };
- const signedOrder = await signatureUtils.ecSignTypedDataOrderAsync(fakeProvider, order, makerAddress);
- expect(signedOrder.signature).to.equal(expectedSignature);
- });
- });
- describe('#convertECSignatureToSignatureHex', () => {
- const ecSignature: ECSignature = {
- v: 27,
- r: '0xaca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d64393',
- s: '0x46b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf2',
- };
- it('should concatenate v,r,s and append the EthSign signature type', async () => {
- const expectedSignatureWithSignatureType =
- '0x1baca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d6439346b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf203';
- const signatureWithSignatureType = signatureUtils.convertECSignatureToSignatureHex(ecSignature);
- expect(signatureWithSignatureType).to.equal(expectedSignatureWithSignatureType);
- });
- });
-});
diff --git a/packages/order-utils/test/sorting_utils_test.ts b/packages/order-utils/test/sorting_utils_test.ts
deleted file mode 100644
index 0b8757496..000000000
--- a/packages/order-utils/test/sorting_utils_test.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import 'mocha';
-
-import { sortingUtils } from '../src';
-
-import { chaiSetup } from './utils/chai_setup';
-import { testOrderFactory } from './utils/test_order_factory';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-describe('sortingUtils', () => {
- describe('#sortOrdersByFeeAdjustedRate', () => {
- const feeRate = new BigNumber(1); // ZRX costs 1 unit of takerAsset per 1 unit of ZRX
- // rate: 2 takerAsset / makerAsset
- const testOrder1 = testOrderFactory.generateTestSignedOrder({
- makerAssetAmount: new BigNumber(100),
- takerAssetAmount: new BigNumber(200),
- });
- // rate: 1 takerAsset / makerAsset
- const testOrder2 = testOrderFactory.generateTestSignedOrder({
- makerAssetAmount: new BigNumber(100),
- takerAssetAmount: new BigNumber(100),
- });
- // rate: 2.5 takerAsset / makerAsset
- const testOrder3 = testOrderFactory.generateTestSignedOrder({
- makerAssetAmount: new BigNumber(100),
- takerAssetAmount: new BigNumber(200),
- takerFee: new BigNumber(50),
- });
- it('correctly sorts by fee adjusted rate when feeRate is Provided', async () => {
- const orders = [testOrder1, testOrder2, testOrder3];
- const sortedOrders = sortingUtils.sortOrdersByFeeAdjustedRate(orders, feeRate);
- expect(sortedOrders).to.deep.equal([testOrder2, testOrder1, testOrder3]);
- });
- it('correctly sorts by fee adjusted rate when no feeRate is Provided', async () => {
- const orders = [testOrder1, testOrder2, testOrder3];
- const sortedOrders = sortingUtils.sortOrdersByFeeAdjustedRate(orders);
- expect(sortedOrders).to.deep.equal([testOrder2, testOrder1, testOrder3]);
- });
- });
- describe('#sortFeeOrdersByFeeAdjustedRate', () => {
- // rate: 200 takerAsset / makerAsset
- const testOrder1 = testOrderFactory.generateTestSignedOrder({
- makerAssetAmount: new BigNumber(100),
- takerAssetAmount: new BigNumber(200),
- takerFee: new BigNumber(99),
- });
- // rate: 1 takerAsset / makerAsset
- const testOrder2 = testOrderFactory.generateTestSignedOrder({
- makerAssetAmount: new BigNumber(100),
- takerAssetAmount: new BigNumber(100),
- });
- // rate: 4 takerAsset / makerAsset
- const testOrder3 = testOrderFactory.generateTestSignedOrder({
- makerAssetAmount: new BigNumber(100),
- takerAssetAmount: new BigNumber(200),
- takerFee: new BigNumber(50),
- });
- it('correctly sorts by fee adjusted rate', async () => {
- const orders = [testOrder1, testOrder2, testOrder3];
- const sortedOrders = sortingUtils.sortFeeOrdersByFeeAdjustedRate(orders);
- expect(sortedOrders).to.deep.equal([testOrder2, testOrder3, testOrder1]);
- });
- });
-});
diff --git a/packages/order-utils/test/utils/chai_setup.ts b/packages/order-utils/test/utils/chai_setup.ts
deleted file mode 100644
index 1a8733093..000000000
--- a/packages/order-utils/test/utils/chai_setup.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import * as chai from 'chai';
-import chaiAsPromised = require('chai-as-promised');
-import ChaiBigNumber = require('chai-bignumber');
-import * as dirtyChai from 'dirty-chai';
-
-export const chaiSetup = {
- configure(): void {
- chai.config.includeStack = true;
- chai.use(ChaiBigNumber());
- chai.use(dirtyChai);
- chai.use(chaiAsPromised);
- },
-};
diff --git a/packages/order-utils/test/utils/simple_erc20_balance_and_proxy_allowance_fetcher.ts b/packages/order-utils/test/utils/simple_erc20_balance_and_proxy_allowance_fetcher.ts
deleted file mode 100644
index d3ea8b456..000000000
--- a/packages/order-utils/test/utils/simple_erc20_balance_and_proxy_allowance_fetcher.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { ERC20TokenContract } from '@0x/abi-gen-wrappers';
-import { BigNumber } from '@0x/utils';
-
-import { AbstractBalanceAndProxyAllowanceFetcher } from '../../src/abstract/abstract_balance_and_proxy_allowance_fetcher';
-
-export class SimpleERC20BalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher {
- private readonly _erc20TokenContract: ERC20TokenContract;
- private readonly _erc20ProxyAddress: string;
- constructor(erc20TokenWrapper: ERC20TokenContract, erc20ProxyAddress: string) {
- this._erc20TokenContract = erc20TokenWrapper;
- this._erc20ProxyAddress = erc20ProxyAddress;
- }
- public async getBalanceAsync(_assetData: string, userAddress: string): Promise<BigNumber> {
- // HACK: We cheat and don't pass in the assetData since it's always the same token used
- // in our tests.
- const balance = await this._erc20TokenContract.balanceOf.callAsync(userAddress);
- return balance;
- }
- public async getProxyAllowanceAsync(_assetData: string, userAddress: string): Promise<BigNumber> {
- // HACK: We cheat and don't pass in the assetData since it's always the same token used
- // in our tests.
- const proxyAllowance = await this._erc20TokenContract.allowance.callAsync(userAddress, this._erc20ProxyAddress);
- return proxyAllowance;
- }
-}
diff --git a/packages/order-utils/test/utils/test_order_factory.ts b/packages/order-utils/test/utils/test_order_factory.ts
deleted file mode 100644
index 4efe0b38e..000000000
--- a/packages/order-utils/test/utils/test_order_factory.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { Order, SignedOrder } from '@0x/types';
-import * as _ from 'lodash';
-
-import { constants } from '../../src/constants';
-import { orderFactory } from '../../src/order_factory';
-
-const BASE_TEST_ORDER: Order = orderFactory.createOrder(
- constants.NULL_ADDRESS,
- constants.ZERO_AMOUNT,
- constants.NULL_ERC20_ASSET_DATA,
- constants.ZERO_AMOUNT,
- constants.NULL_ERC20_ASSET_DATA,
- constants.NULL_ADDRESS,
-);
-const BASE_TEST_SIGNED_ORDER: SignedOrder = {
- ...BASE_TEST_ORDER,
- signature: constants.NULL_BYTES,
-};
-
-export const testOrderFactory = {
- generateTestSignedOrder(partialOrder: Partial<SignedOrder>): SignedOrder {
- return transformObject(BASE_TEST_SIGNED_ORDER, partialOrder);
- },
- generateTestSignedOrders(partialOrder: Partial<SignedOrder>, numOrders: number): SignedOrder[] {
- const baseTestOrders = _.map(_.range(numOrders), () => BASE_TEST_SIGNED_ORDER);
- return _.map(baseTestOrders, order => transformObject(order, partialOrder));
- },
-};
-
-function transformObject<T>(input: T, transformation: Partial<T>): T {
- const copy = _.cloneDeep(input);
- return _.assign(copy, transformation);
-}
diff --git a/packages/order-utils/test/utils/web3_wrapper.ts b/packages/order-utils/test/utils/web3_wrapper.ts
deleted file mode 100644
index accfcb7fe..000000000
--- a/packages/order-utils/test/utils/web3_wrapper.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { web3Factory } from '@0x/dev-utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import { Provider } from 'ethereum-types';
-
-const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true });
-const web3Wrapper = new Web3Wrapper(provider);
-
-export { provider, web3Wrapper };
diff --git a/packages/order-utils/tsconfig.json b/packages/order-utils/tsconfig.json
deleted file mode 100644
index 718e623c7..000000000
--- a/packages/order-utils/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "extends": "../../tsconfig",
- "compilerOptions": {
- "outDir": "lib",
- "rootDir": "."
- },
- "include": ["src/**/*", "test/**/*"]
-}
diff --git a/packages/order-utils/tslint.json b/packages/order-utils/tslint.json
deleted file mode 100644
index dd9053357..000000000
--- a/packages/order-utils/tslint.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": ["@0x/tslint-config"]
-}
diff --git a/packages/order-utils/typedoc-tsconfig.json b/packages/order-utils/typedoc-tsconfig.json
deleted file mode 100644
index b9c6b36f3..000000000
--- a/packages/order-utils/typedoc-tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "extends": "../../typedoc-tsconfig",
- "compilerOptions": {
- "outDir": "lib"
- },
- "include": ["src/**/*", "test/**/*"]
-}