Compare commits
297 Commits
@0xproject
...
@0xproject
Author | SHA1 | Date | |
---|---|---|---|
|
f364b5c5ab | ||
|
6486fced34 | ||
|
bc9f2a51a2 | ||
|
9c03b54d75 | ||
|
eae08ea1e4 | ||
|
6f276223c6 | ||
|
21effcaa8b | ||
|
114b31a813 | ||
|
1a1b7a2bc4 | ||
|
c9b213839a | ||
|
4043fa76cc | ||
|
9c8e3bc4c9 | ||
|
18b1f01641 | ||
|
9085c674e4 | ||
|
b5d19d3fb1 | ||
|
cc0477153b | ||
|
76008b41c5 | ||
|
8193fdc304 | ||
|
9d06c81078 | ||
|
cdf85e5eee | ||
|
d774dbc432 | ||
|
0369f5ebc4 | ||
|
1e6b11b27e | ||
|
7a8231435b | ||
|
b1aa7725df | ||
|
bfe0ba3e9a | ||
|
2d39329ee7 | ||
|
761b0063a0 | ||
|
0f27ce3424 | ||
|
2b0c0a6ff7 | ||
|
5bd96f6fe9 | ||
|
37ac6749ba | ||
|
bf955bd87f | ||
|
6bd921d0bc | ||
|
534decea95 | ||
|
267830d463 | ||
|
e82d0c21ec | ||
|
ece6417699 | ||
|
74d5449719 | ||
|
4af7ff9cc3 | ||
|
46dedfcb67 | ||
|
a9fa1a0df6 | ||
|
a8572b4944 | ||
|
91c0d47ad4 | ||
|
fd2611794a | ||
|
1fe1c5321b | ||
|
f063a5db0f | ||
|
3883315447 | ||
|
7679e07957 | ||
|
c39ba37ad8 | ||
|
f1c3840c3b | ||
|
e5c5b36a73 | ||
|
c51f7a8375 | ||
|
e53e2ac31b | ||
|
b72857cd8b | ||
|
cc223b9eab | ||
|
f2c49e8b37 | ||
|
9b6476a6b7 | ||
|
d8898cf9a3 | ||
|
34df5af295 | ||
|
3de88d5345 | ||
|
9ab6ab1bf9 | ||
|
b6de0bdd43 | ||
|
a2b62fd808 | ||
|
f9c4d0925e | ||
|
1df9370bc2 | ||
|
7d840c7a18 | ||
|
74c0fd419b | ||
|
6f540e3e58 | ||
|
886a03fdcd | ||
|
81007c453c | ||
|
6529e06057 | ||
|
55336f96d7 | ||
|
3a18c249f5 | ||
|
7c0775aa1b | ||
|
ba92754669 | ||
|
30afd39129 | ||
|
41699406cf | ||
|
29d5034260 | ||
|
00d1622b3f | ||
|
a1acf19ff3 | ||
|
c839965c05 | ||
|
f99232095b | ||
|
5044fe4fe4 | ||
|
8e49169e6b | ||
|
c71781d9ab | ||
|
8a2a4052f3 | ||
|
dad557164e | ||
|
e2fb49a8f8 | ||
|
f3241ff86a | ||
|
b9e7973a0f | ||
|
004b1f5288 | ||
|
857bd24c6d | ||
|
904968cf4a | ||
|
83747934ad | ||
|
7f90f5ecd4 | ||
|
12f02b9814 | ||
|
8931388309 | ||
|
25160d7344 | ||
|
ab6bf6edc7 | ||
|
56a4a374cd | ||
|
caa5b4e342 | ||
|
b6172c3965 | ||
|
02ddfa07a7 | ||
|
5022878680 | ||
|
2bfacbb8ba | ||
|
b18d2b0274 | ||
|
f20b496dca | ||
|
cca17f70b8 | ||
|
b8e69718a1 | ||
|
50ed7d2af2 | ||
|
698de932ed | ||
|
a3d8858bb1 | ||
|
83f3ba21b8 | ||
|
2aa729b212 | ||
|
1de70e4474 | ||
|
f2393de59b | ||
|
94ea7cc451 | ||
|
f8dbf57582 | ||
|
c59cd36da6 | ||
|
15e92958d6 | ||
|
96c648c4b4 | ||
|
f56a7d0cb2 | ||
|
01e617bb83 | ||
|
59fd5c69c0 | ||
|
28a9a8c380 | ||
|
6c2796b433 | ||
|
82ad5f7897 | ||
|
bf8ac3b9e6 | ||
|
edcdc9b1b9 | ||
|
4227aaa68a | ||
|
b750ce8be6 | ||
|
03a6a088c5 | ||
|
1e787a7646 | ||
|
766ac3f1fe | ||
|
a9038f2afc | ||
|
9828fa335e | ||
|
0c04d490bb | ||
|
e9589ff786 | ||
|
c3bd3437f5 | ||
|
01789e6750 | ||
|
c3f7ba1b91 | ||
|
90d72a3683 | ||
|
f9bcf936ed | ||
|
acff177c54 | ||
|
658214a2e2 | ||
|
55f6f02c9b | ||
|
c5ba52910a | ||
|
994ccd6694 | ||
|
4921a83813 | ||
|
a97ba41b86 | ||
|
67e2623d2c | ||
|
4111095da3 | ||
|
6c21ddcedb | ||
|
d86349658f | ||
|
151ce6e3c7 | ||
|
6bdee26c30 | ||
|
5e4b1eed30 | ||
|
ab5cd95ccc | ||
|
a3dc398da5 | ||
|
b70f5d1a1e | ||
|
26363931ed | ||
|
e2438330f5 | ||
|
c5fcdd0657 | ||
|
345f3c07a5 | ||
|
f3477ff28c | ||
|
7ac4fa50b5 | ||
|
2f0a914838 | ||
|
5fc7d9a603 | ||
|
ced68e4e02 | ||
|
80071beaac | ||
|
de1029d5ef | ||
|
ffeb3194a8 | ||
|
95e9f33f6a | ||
|
c599a20b34 | ||
|
ca59528a32 | ||
|
6f4fd06d38 | ||
|
4715c2d006 | ||
|
fcfa43b6f1 | ||
|
56b4c55654 | ||
|
830790eeac | ||
|
39de9c7879 | ||
|
7b6cc14b71 | ||
|
ec749a4033 | ||
|
fe32214613 | ||
|
f6fcb775b7 | ||
|
d209108a95 | ||
|
efc64cf17f | ||
|
2f41ed50c1 | ||
|
fcc8cdd36a | ||
|
248632ce76 | ||
|
25681754bd | ||
|
179c487da9 | ||
|
350989bbec | ||
|
f5293e6c38 | ||
|
70c3515c94 | ||
|
4c7fd5a4e8 | ||
|
9d24341d94 | ||
|
512502ca08 | ||
|
6ce662c7a4 | ||
|
701ea5c46b | ||
|
2e5ff53d72 | ||
|
1229c61ba4 | ||
|
ee54438e92 | ||
|
65af78c85d | ||
|
b4747c3f85 | ||
|
1df074b73e | ||
|
254d30b8df | ||
|
ac5588c7c4 | ||
|
ddb70a89ad | ||
|
f4b2a9625d | ||
|
c2a1317c38 | ||
|
49f1a6933c | ||
|
9b387b8ec3 | ||
|
a45a29432e | ||
|
819d069edc | ||
|
b0a57a5091 | ||
|
d8678d562d | ||
|
34a9035164 | ||
|
0941e0a929 | ||
|
1ee78062d7 | ||
|
09f5609618 | ||
|
098322c564 | ||
|
365e24c1cd | ||
|
b82fdd59e7 | ||
|
6190ac7791 | ||
|
ed3aeb7997 | ||
|
33f92b6bcf | ||
|
9131a72a47 | ||
|
e5617dfe61 | ||
|
e67d67419f | ||
|
17c34716f9 | ||
|
e12f7c3026 | ||
|
af395eccda | ||
|
c403dcdabf | ||
|
c500cc095f | ||
|
6ecda647ad | ||
|
3e7ee1f090 | ||
|
0c120cb7a3 | ||
|
cab6829df9 | ||
|
0efe6df416 | ||
|
a4b6112a31 | ||
|
47debf0134 | ||
|
16ddd1edfc | ||
|
0f1fd0e90d | ||
|
ef76d83d2a | ||
|
df9f6004f2 | ||
|
9a87f99dcd | ||
|
30011db6d7 | ||
|
b6ac132c78 | ||
|
abf87a643d | ||
|
3824ea9079 | ||
|
5e22ce05c5 | ||
|
8fcc7aefa7 | ||
|
0b6ea1d046 | ||
|
22d3981a74 | ||
|
81b4f4928d | ||
|
dd77a38535 | ||
|
d319b53e23 | ||
|
b9627e14d0 | ||
|
56a96d36a1 | ||
|
e60630fa73 | ||
|
5ef6613024 | ||
|
af7e02de27 | ||
|
51d5b9d35d | ||
|
092ca6bcf5 | ||
|
2625cbbfed | ||
|
cedd1d5596 | ||
|
fb9e14a229 | ||
|
4e1bd7b5f0 | ||
|
5dfed8cd00 | ||
|
a2672a0d78 | ||
|
ee5ac6b800 | ||
|
a481d2ab46 | ||
|
c8bb21d12d | ||
|
e817cd7d43 | ||
|
bd6085fffd | ||
|
7efe9a9385 | ||
|
50da40a727 | ||
|
48390a1875 | ||
|
a3d27cd128 | ||
|
589c814ee6 | ||
|
4b60a3cbab | ||
|
1aaf633df8 | ||
|
82771ec64a | ||
|
ada8a402da | ||
|
17956efe35 | ||
|
8378c9f85e | ||
|
324b1079e7 | ||
|
c6da829713 | ||
|
844b0687a6 | ||
|
2ed2dd2fb7 | ||
|
d2f7dd3d5a | ||
|
9f08916cf1 | ||
|
a0e3676e3a | ||
|
2276793629 | ||
|
cfe57f52f4 |
@@ -64,7 +64,8 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn wsrun test:circleci @0xproject/0x.js
|
||||
- run: yarn wsrun test:circleci 0x.js
|
||||
- run: yarn wsrun test:circleci @0xproject/abi-gen
|
||||
- run: yarn wsrun test:circleci @0xproject/assert
|
||||
- run: yarn wsrun test:circleci @0xproject/base-contract
|
||||
- run: yarn wsrun test:circleci @0xproject/connect
|
||||
@@ -83,6 +84,10 @@ jobs:
|
||||
key: coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/0x.js/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-abi-gen-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/abi-gen/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
@@ -160,6 +165,9 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-abi-gen-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
|
||||
|
@@ -10,7 +10,7 @@ lib
|
||||
/packages/migrations/src/1.0.0/contract_wrappers
|
||||
/packages/migrations/src/2.0.0/contract_wrappers
|
||||
/packages/migrations/src/2.0.0-beta-testnet/contract_wrappers
|
||||
/packages/0x.js/test/artifacts
|
||||
/packages/0x.js/src/artifacts
|
||||
/packages/contracts/src/artifacts
|
||||
/packages/metacoin/artifacts
|
||||
/packages/contract-wrappers/test/artifacts
|
||||
|
@@ -8,11 +8,13 @@
|
||||
|
||||
## Types of changes
|
||||
|
||||
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
||||
<!--- What types of changes does your code introduce? Uncomment all the bullets that apply: -->
|
||||
|
||||
* [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
* [ ] New feature (non-breaking change which adds functionality)
|
||||
* [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
||||
<!-- * Bug fix (non-breaking change which fixes an issue) -->
|
||||
|
||||
<!-- * New feature (non-breaking change which adds functionality) -->
|
||||
|
||||
<!-- * Breaking change (fix or feature that would cause existing functionality to change) -->
|
||||
|
||||
## Checklist:
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"lerna": "2.5.1",
|
||||
"lerna": "3.0.0-beta.14",
|
||||
"packages": ["packages/*"],
|
||||
"commands": {
|
||||
"publish": {
|
||||
|
@@ -31,7 +31,7 @@
|
||||
"stage_docs": "wsrun docs:stage $PKG --fast-exit --parallel --exclude-missing",
|
||||
"lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing",
|
||||
"comment:postinstall": "HACK: For some reason `yarn` is not setting up symlinks properly for order-utils. We temporarily set them manually. Remove this after V2 refactor is complete.",
|
||||
"postinstall": "rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/assert `pwd`/packages/order-utils/node_modules/@0xproject/assert; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -f `pwd`/packages/contracts/node_modules/@0xproject/types; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types; rm -rf `pwd`/packages/fill-scenarios/node_modules/@0xproject; mkdir -p `pwd`/packages/fill-scenarios/node_modules/@0xproject; ln -s `pwd`/packages/types `pwd`/packages/fill-scenarios/node_modules/@0xproject/types; ln -s `pwd`/packages/json-schemas `pwd`/packages/fill-scenarios/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/fill-scenarios/node_modules/@0xproject/order-utils; rm -rf `pwd`/packages/contract-wrappers/node_modules/@0xproject; mkdir -p `pwd`/packages/contract-wrappers/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contract-wrappers/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/assert `pwd`/packages/contract-wrappers/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/contract-wrappers/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/contract-wrappers/node_modules/@0xproject/types; ln -s `pwd`/packages/fill-scenarios `pwd`/packages/contract-wrappers/node_modules/@0xproject/fill-scenarios; rm -rf `pwd`/packages/assert/node_modules/@0xproject; mkdir -p `pwd`/packages/assert/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/assert/node_modules/@0xproject/json-schemas"
|
||||
"postinstall": "rm -rf `pwd`/packages/0x.js/node_modules/@0xproject; mkdir `pwd`/packages/0x.js/node_modules/@0xproject; ln -s `pwd`/packages/contract-wrappers `pwd`/packages/0x.js/node_modules/@0xproject/contract-wrappers; ln -s `pwd`/packages/order-utils `pwd`/packages/0x.js/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/types `pwd`/packages/0x.js/node_modules/@0xproject/types; rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/assert `pwd`/packages/order-utils/node_modules/@0xproject/assert; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -rf `pwd`/packages/fill-scenarios/node_modules/@0xproject; mkdir -p `pwd`/packages/fill-scenarios/node_modules/@0xproject; ln -s `pwd`/packages/types `pwd`/packages/fill-scenarios/node_modules/@0xproject/types; ln -s `pwd`/packages/json-schemas `pwd`/packages/fill-scenarios/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/fill-scenarios/node_modules/@0xproject/order-utils; rm -rf `pwd`/packages/contract-wrappers/node_modules/@0xproject; mkdir -p `pwd`/packages/contract-wrappers/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contract-wrappers/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/assert `pwd`/packages/contract-wrappers/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/contract-wrappers/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/contract-wrappers/node_modules/@0xproject/types; ln -s `pwd`/packages/fill-scenarios `pwd`/packages/contract-wrappers/node_modules/@0xproject/fill-scenarios; rm -rf `pwd`/packages/assert/node_modules/@0xproject; mkdir -p `pwd`/packages/assert/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/assert/node_modules/@0xproject/json-schemas; rm -rf `pwd`/packages/order-watcher/node_modules/@0xproject; mkdir `pwd`/packages/order-watcher/node_modules/@0xproject; ln -s `pwd`/packages/assert `pwd`/packages/order-watcher/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-watcher/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/order-watcher/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/types `pwd`/packages/order-watcher/node_modules/@0xproject/types; ln -s `pwd`/packages/contract-wrappers `pwd`/packages/order-watcher/node_modules/@0xproject/contract-wrappers; rm -rf `pwd`/packages/contracts/node_modules/@0xproject; mkdir `pwd`/packages/contracts/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contracts/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types; rm -rf `pwd`/packages/migrations/node_modules/@0xproject; mkdir `pwd`/packages/migrations/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/migrations/node_modules/@0xproject/order-utils"
|
||||
},
|
||||
"config": {
|
||||
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
||||
@@ -41,7 +41,7 @@
|
||||
"coveralls": "^3.0.0",
|
||||
"ganache-cli": "6.1.3",
|
||||
"lcov-result-merger": "^3.0.0",
|
||||
"lerna": "^2.5.1",
|
||||
"lerna": "3.0.0-beta.14",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"prettier": "^1.11.1",
|
||||
"wsrun": "^2.2.0",
|
||||
|
@@ -1,4 +1,66 @@
|
||||
[
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Remove tokenRegistry wrapper",
|
||||
"pr": 863
|
||||
},
|
||||
{
|
||||
"note": "Rename zeroEx.token to zeroEx.erc20Token, and add zeroEx.erc721Token",
|
||||
"pr": 863
|
||||
},
|
||||
{
|
||||
"note": "Rename zeroEx.proxy to zeroEx.erc20Proxy and add zeroEx.erc721Proxy",
|
||||
"pr": 863
|
||||
},
|
||||
{
|
||||
"note":
|
||||
"Refactored ZeroEx.isValidSignature to zeroEx.isValidSignatureAsync. It is now async so that it can verify contract-dependent signature types",
|
||||
"pr": 863
|
||||
},
|
||||
{
|
||||
"note":
|
||||
"Refactored signOrderHashAsync to ecSignOrderHashAsync. There are now many non-ECSignature ways to sign orders too.",
|
||||
"pr": 863
|
||||
},
|
||||
{
|
||||
"note":
|
||||
"Removed createOrderWatcherAsync method. Will be added back once OrderWatcher is refactored for V2",
|
||||
"pr": 863
|
||||
},
|
||||
{
|
||||
"note": "0x.js exports renamed contract events and event arg types",
|
||||
"pr": 863
|
||||
},
|
||||
{
|
||||
"note": "Remove stateLayer config from OrderWatcher. It now always operates on the latest block",
|
||||
"pr": 875
|
||||
},
|
||||
{
|
||||
"note": "Export ZeroEx.assetData with methods to decode/encode assetData fields found in 0x orders",
|
||||
"pr": 884
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531919263,
|
||||
"version": "0.38.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531149657,
|
||||
"version": "0.38.5",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1529397769,
|
||||
"version": "0.38.4",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.38.6 - _July 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.38.5 - _July 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.38.4 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "0x.js",
|
||||
"version": "0.38.4",
|
||||
"version": "0.38.6",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -18,9 +18,10 @@
|
||||
"watch_without_deps": "yarn pre_build && tsc -w",
|
||||
"build": "yarn pre_build && yarn build:all && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
|
||||
"build:all": "run-p build:umd:prod build:commonjs; exit 0;",
|
||||
"pre_build": "run-s generate_contract_wrappers copy_artifacts",
|
||||
"copy_artifacts": "copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts",
|
||||
"generate_contract_wrappers": "abi-gen --abis 'src/compact_artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers",
|
||||
"pre_build": "run-s update_artifacts generate_contract_wrappers",
|
||||
"copy_artifacts": "copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts",
|
||||
"update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json src/artifacts; done;",
|
||||
"generate_contract_wrappers": "abi-gen --abis 'src/artifacts/@(ZRXToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers",
|
||||
"lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/*",
|
||||
"test:circleci": "run-s test:coverage",
|
||||
"test": "yarn run_mocha",
|
||||
@@ -29,7 +30,7 @@
|
||||
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
|
||||
"clean": "shx rm -rf _bundles lib test_temp scripts src/generated_contract_wrappers",
|
||||
"build:umd:prod": "NODE_ENV=production webpack",
|
||||
"build:commonjs": "tsc && copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
|
||||
"build:commonjs": "tsc && yarn copy_artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
|
||||
"manual:postpublish": "yarn build; node ./scripts/postpublish.js",
|
||||
"docs:stage": "node scripts/stage_docs.js",
|
||||
@@ -37,7 +38,7 @@
|
||||
"upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json"
|
||||
},
|
||||
"config": {
|
||||
"compact_artifacts": "Exchange DummyToken ZRXToken Token EtherToken TokenTransferProxy TokenRegistry",
|
||||
"contracts": "ZRXToken",
|
||||
"postpublish": {
|
||||
"assets": [
|
||||
"packages/0x.js/_bundles/index.js",
|
||||
@@ -69,12 +70,11 @@
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@0xproject/abi-gen": "^0.3.2",
|
||||
"@0xproject/dev-utils": "^0.4.4",
|
||||
"@0xproject/migrations": "^0.0.8",
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/sol-compiler": "^0.5.2",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@0xproject/abi-gen": "^1.0.0",
|
||||
"@0xproject/dev-utils": "^1.0.0",
|
||||
"@0xproject/migrations": "^0.0.10",
|
||||
"@0xproject/monorepo-script": "^1.0.0",
|
||||
"@0xproject/tslint-config": "^1.0.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "^8.0.53",
|
||||
@@ -94,23 +94,23 @@
|
||||
"shx": "^0.2.2",
|
||||
"sinon": "^4.0.0",
|
||||
"source-map-support": "^0.5.0",
|
||||
"tslint": "5.8.0",
|
||||
"tslint": "5.11.0",
|
||||
"typedoc": "0xProject/typedoc",
|
||||
"typescript": "2.7.1",
|
||||
"webpack": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/assert": "^0.2.12",
|
||||
"@0xproject/base-contract": "^0.3.4",
|
||||
"@0xproject/contract-wrappers": "^0.0.5",
|
||||
"@0xproject/order-utils": "^0.0.7",
|
||||
"@0xproject/order-watcher": "^0.0.6",
|
||||
"@0xproject/sol-compiler": "^0.5.2",
|
||||
"@0xproject/types": "^0.8.1",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"@0xproject/web3-wrapper": "^0.7.1",
|
||||
"ethereum-types": "^0.0.2",
|
||||
"@0xproject/assert": "^1.0.0",
|
||||
"@0xproject/base-contract": "^1.0.0",
|
||||
"@0xproject/contract-wrappers": "^0.1.1",
|
||||
"@0xproject/order-utils": "^1.0.0-rc.1",
|
||||
"@0xproject/sol-compiler": "^1.0.0",
|
||||
"@0xproject/subproviders": "^1.0.0",
|
||||
"@0xproject/types": "^1.0.0-rc.1",
|
||||
"@0xproject/typescript-typings": "^1.0.0",
|
||||
"@0xproject/utils": "^1.0.0",
|
||||
"@0xproject/web3-wrapper": "^1.0.0",
|
||||
"ethereum-types": "^1.0.0",
|
||||
"ethers": "3.0.22",
|
||||
"lodash": "^4.17.4"
|
||||
},
|
||||
|
@@ -2,23 +2,28 @@ import { assert } from '@0xproject/assert';
|
||||
import {
|
||||
ContractWrappers,
|
||||
ContractWrappersConfig,
|
||||
ERC20ProxyWrapper,
|
||||
ERC20TokenWrapper,
|
||||
ERC721ProxyWrapper,
|
||||
ERC721TokenWrapper,
|
||||
EtherTokenWrapper,
|
||||
ExchangeWrapper,
|
||||
TokenRegistryWrapper,
|
||||
TokenTransferProxyWrapper,
|
||||
TokenWrapper,
|
||||
} from '@0xproject/contract-wrappers';
|
||||
import {
|
||||
assetDataUtils,
|
||||
ecSignOrderHashAsync,
|
||||
generatePseudoRandomSalt,
|
||||
getOrderHashHex,
|
||||
isValidOrderHash,
|
||||
isValidSignature,
|
||||
signOrderHashAsync,
|
||||
isValidSignatureAsync,
|
||||
MessagePrefixOpts,
|
||||
orderHashUtils,
|
||||
} from '@0xproject/order-utils';
|
||||
import { OrderWatcher, OrderWatcherConfig } from '@0xproject/order-watcher';
|
||||
import { ECSignature, Order, Provider, SignedOrder, TransactionReceiptWithDecodedLogs } from '@0xproject/types';
|
||||
// HACK: Since we export assetDataUtils from ZeroEx and it has AssetProxyId, ERC20AssetData and ERC721AssetData
|
||||
// in it's public interface, we need to import these types here.
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
import { AssetProxyId, ECSignature, ERC20AssetData, ERC721AssetData, Order, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
|
||||
import { constants } from './utils/constants';
|
||||
|
||||
@@ -33,30 +38,38 @@ export class ZeroEx {
|
||||
* this constant for your convenience.
|
||||
*/
|
||||
public static NULL_ADDRESS = constants.NULL_ADDRESS;
|
||||
/**
|
||||
* A set of methods to easily decode/encode assetData fields found in 0x orders.
|
||||
*/
|
||||
public static assetData = assetDataUtils;
|
||||
/**
|
||||
* An instance of the ExchangeWrapper class containing methods for interacting with the 0x Exchange smart contract.
|
||||
*/
|
||||
public exchange: ExchangeWrapper;
|
||||
/**
|
||||
* An instance of the TokenRegistryWrapper class containing methods for interacting with the 0x
|
||||
* TokenRegistry smart contract.
|
||||
* An instance of the ERC20TokenWrapper class containing methods for interacting with any ERC20 token smart contract.
|
||||
*/
|
||||
public tokenRegistry: TokenRegistryWrapper;
|
||||
public erc20Token: ERC20TokenWrapper;
|
||||
/**
|
||||
* An instance of the TokenWrapper class containing methods for interacting with any ERC20 token smart contract.
|
||||
* An instance of the ERC721TokenWrapper class containing methods for interacting with any ERC721 token smart contract.
|
||||
*/
|
||||
public token: TokenWrapper;
|
||||
public erc721Token: ERC721TokenWrapper;
|
||||
/**
|
||||
* An instance of the EtherTokenWrapper class containing methods for interacting with the
|
||||
* wrapped ETH ERC20 token smart contract.
|
||||
*/
|
||||
public etherToken: EtherTokenWrapper;
|
||||
/**
|
||||
* An instance of the TokenTransferProxyWrapper class containing methods for interacting with the
|
||||
* tokenTransferProxy smart contract.
|
||||
* An instance of the ERC20ProxyWrapper class containing methods for interacting with the
|
||||
* ERC20 proxy smart contract.
|
||||
*/
|
||||
public proxy: TokenTransferProxyWrapper;
|
||||
private _contractWrappers: ContractWrappers;
|
||||
public erc20Proxy: ERC20ProxyWrapper;
|
||||
/**
|
||||
* An instance of the ERC721ProxyWrapper class containing methods for interacting with the
|
||||
* ERC721 proxy smart contract.
|
||||
*/
|
||||
public erc721Proxy: ERC721ProxyWrapper;
|
||||
private readonly _contractWrappers: ContractWrappers;
|
||||
/**
|
||||
* Generates a pseudo-random 256-bit salt.
|
||||
* The salt can be included in a 0x order, ensuring that the order generates a unique orderHash
|
||||
@@ -66,24 +79,13 @@ export class ZeroEx {
|
||||
public static generatePseudoRandomSalt(): BigNumber {
|
||||
return generatePseudoRandomSalt();
|
||||
}
|
||||
/**
|
||||
* Verifies that the elliptic curve signature `signature` was generated
|
||||
* by signing `data` with the private key corresponding to the `signerAddress` address.
|
||||
* @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 signature is valid for the supplied signerAddress and data.
|
||||
*/
|
||||
public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
|
||||
return isValidSignature(data, signature, signerAddress);
|
||||
}
|
||||
/**
|
||||
* Computes the orderHash for a supplied order.
|
||||
* @param order An object that conforms to the Order or SignedOrder interface definitions.
|
||||
* @return The resulting orderHash from hashing the supplied order.
|
||||
*/
|
||||
public static getOrderHashHex(order: Order | SignedOrder): string {
|
||||
return getOrderHashHex(order);
|
||||
return orderHashUtils.getOrderHashHex(order);
|
||||
}
|
||||
/**
|
||||
* Checks if the supplied hex encoded order hash is valid.
|
||||
@@ -93,7 +95,7 @@ export class ZeroEx {
|
||||
* @return Whether the supplied orderHash has the expected format.
|
||||
*/
|
||||
public static isValidOrderHash(orderHash: string): boolean {
|
||||
return isValidOrderHash(orderHash);
|
||||
return orderHashUtils.isValidOrderHash(orderHash);
|
||||
}
|
||||
/**
|
||||
* A unit amount is defined as the amount of a token above the specified decimal places (integer part).
|
||||
@@ -134,12 +136,29 @@ export class ZeroEx {
|
||||
assert.isWeb3Provider('provider', provider);
|
||||
this._contractWrappers = new ContractWrappers(provider, config);
|
||||
|
||||
this.proxy = this._contractWrappers.proxy;
|
||||
this.token = this._contractWrappers.token;
|
||||
this.erc20Proxy = this._contractWrappers.erc20Proxy;
|
||||
this.erc721Proxy = this._contractWrappers.erc721Proxy;
|
||||
this.erc20Token = this._contractWrappers.erc20Token;
|
||||
this.erc721Token = this._contractWrappers.erc721Token;
|
||||
this.exchange = this._contractWrappers.exchange;
|
||||
this.tokenRegistry = this._contractWrappers.tokenRegistry;
|
||||
this.etherToken = this._contractWrappers.etherToken;
|
||||
}
|
||||
/**
|
||||
* 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 The hex encoded signature.
|
||||
* @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.
|
||||
*/
|
||||
public async isValidSignatureAsync(data: string, signature: string, signerAddress: string): Promise<boolean> {
|
||||
const isValid = await isValidSignatureAsync(
|
||||
this._contractWrappers.getProvider(),
|
||||
data,
|
||||
signature,
|
||||
signerAddress,
|
||||
);
|
||||
return isValid;
|
||||
}
|
||||
/**
|
||||
* Sets a new web3 provider for 0x.js. Updating the provider will stop all
|
||||
* subscriptions so you will need to re-subscribe to all events relevant to your app after this call.
|
||||
@@ -172,23 +191,21 @@ export class ZeroEx {
|
||||
* @param orderHash Hex encoded orderHash to sign.
|
||||
* @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address
|
||||
* must be available via the Provider supplied to 0x.js.
|
||||
* @param shouldAddPersonalMessagePrefix Some signers add the personal message prefix `\x19Ethereum Signed Message`
|
||||
* themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
|
||||
* (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
|
||||
* before sending the request.
|
||||
* @param MessagePrefixOpts Options regarding the desired prefix and whether to add it before calling `eth_sign`
|
||||
* @return An object containing the Elliptic curve signature parameters generated by signing the orderHash.
|
||||
*/
|
||||
public async signOrderHashAsync(
|
||||
public async ecSignOrderHashAsync(
|
||||
orderHash: string,
|
||||
signerAddress: string,
|
||||
shouldAddPersonalMessagePrefix: boolean,
|
||||
messagePrefixOpts: MessagePrefixOpts,
|
||||
): Promise<ECSignature> {
|
||||
return signOrderHashAsync(
|
||||
const signature = await ecSignOrderHashAsync(
|
||||
this._contractWrappers.getProvider(),
|
||||
orderHash,
|
||||
signerAddress,
|
||||
shouldAddPersonalMessagePrefix,
|
||||
messagePrefixOpts,
|
||||
);
|
||||
return signature;
|
||||
}
|
||||
/**
|
||||
* Waits for a transaction to be mined and returns the transaction receipt.
|
||||
@@ -211,18 +228,4 @@ export class ZeroEx {
|
||||
);
|
||||
return transactionReceiptWithDecodedLogs;
|
||||
}
|
||||
/**
|
||||
* Instantiates and returns a new OrderWatcher instance.
|
||||
* Defaults to watching the pending state.
|
||||
* @param config The configuration object. Look up the type for the description.
|
||||
* @return An instance of the 0x.js OrderWatcher class.
|
||||
*/
|
||||
public async createOrderWatcherAsync(config?: OrderWatcherConfig): Promise<OrderWatcher> {
|
||||
// Hack: Get Web3Wrapper from ContractWrappers
|
||||
const web3Wrapper: Web3Wrapper = (this._contractWrappers as any)._web3Wrapper;
|
||||
const networkId = await web3Wrapper.getNetworkIdAsync();
|
||||
const provider = this._contractWrappers.getProvider();
|
||||
const orderWatcher = new OrderWatcher(provider, networkId, config);
|
||||
return orderWatcher;
|
||||
}
|
||||
}
|
||||
|
7
packages/0x.js/src/artifacts.ts
Normal file
7
packages/0x.js/src/artifacts.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { ContractArtifact } from '@0xproject/sol-compiler';
|
||||
|
||||
import * as ZRXToken from './artifacts/ZRXToken.json';
|
||||
|
||||
export const artifacts = {
|
||||
ZRXToken: (ZRXToken as any) as ContractArtifact,
|
||||
};
|
10031
packages/0x.js/src/artifacts/ZRXToken.json
Normal file
10031
packages/0x.js/src/artifacts/ZRXToken.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"contract_name": "DummyToken",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setBalance",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,287 +0,0 @@
|
||||
{
|
||||
"contract_name": "EtherToken",
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "withdraw",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "deposit",
|
||||
"outputs": [],
|
||||
"payable": true,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"payable": true,
|
||||
"type": "fallback"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Deposit",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Withdrawal",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
|
||||
},
|
||||
"3": {
|
||||
"address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
|
||||
},
|
||||
"4": {
|
||||
"address": "0xc778417e063141139fce010982780140aa0cd5ab"
|
||||
},
|
||||
"42": {
|
||||
"address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,610 +0,0 @@
|
||||
{
|
||||
"contract_name": "Exchange",
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "numerator",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "denominator",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "target",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "isRoundingError",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "filled",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "cancelled",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderAddresses",
|
||||
"type": "address[5][]"
|
||||
},
|
||||
{
|
||||
"name": "orderValues",
|
||||
"type": "uint256[6][]"
|
||||
},
|
||||
{
|
||||
"name": "fillTakerTokenAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "shouldThrowOnInsufficientBalanceOrAllowance",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "v",
|
||||
"type": "uint8[]"
|
||||
},
|
||||
{
|
||||
"name": "r",
|
||||
"type": "bytes32[]"
|
||||
},
|
||||
{
|
||||
"name": "s",
|
||||
"type": "bytes32[]"
|
||||
}
|
||||
],
|
||||
"name": "fillOrdersUpTo",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderAddresses",
|
||||
"type": "address[5]"
|
||||
},
|
||||
{
|
||||
"name": "orderValues",
|
||||
"type": "uint256[6]"
|
||||
},
|
||||
{
|
||||
"name": "cancelTakerTokenAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "cancelOrder",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "ZRX_TOKEN_CONTRACT",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderAddresses",
|
||||
"type": "address[5][]"
|
||||
},
|
||||
{
|
||||
"name": "orderValues",
|
||||
"type": "uint256[6][]"
|
||||
},
|
||||
{
|
||||
"name": "fillTakerTokenAmounts",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"name": "v",
|
||||
"type": "uint8[]"
|
||||
},
|
||||
{
|
||||
"name": "r",
|
||||
"type": "bytes32[]"
|
||||
},
|
||||
{
|
||||
"name": "s",
|
||||
"type": "bytes32[]"
|
||||
}
|
||||
],
|
||||
"name": "batchFillOrKillOrders",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderAddresses",
|
||||
"type": "address[5]"
|
||||
},
|
||||
{
|
||||
"name": "orderValues",
|
||||
"type": "uint256[6]"
|
||||
},
|
||||
{
|
||||
"name": "fillTakerTokenAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "v",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "r",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "s",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "fillOrKillOrder",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderHash",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "getUnavailableTakerTokenAmount",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "hash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "v",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "r",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "s",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "isValidSignature",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "numerator",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "denominator",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "target",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getPartialAmount",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "TOKEN_TRANSFER_PROXY_CONTRACT",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderAddresses",
|
||||
"type": "address[5][]"
|
||||
},
|
||||
{
|
||||
"name": "orderValues",
|
||||
"type": "uint256[6][]"
|
||||
},
|
||||
{
|
||||
"name": "fillTakerTokenAmounts",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"name": "shouldThrowOnInsufficientBalanceOrAllowance",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "v",
|
||||
"type": "uint8[]"
|
||||
},
|
||||
{
|
||||
"name": "r",
|
||||
"type": "bytes32[]"
|
||||
},
|
||||
{
|
||||
"name": "s",
|
||||
"type": "bytes32[]"
|
||||
}
|
||||
],
|
||||
"name": "batchFillOrders",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderAddresses",
|
||||
"type": "address[5][]"
|
||||
},
|
||||
{
|
||||
"name": "orderValues",
|
||||
"type": "uint256[6][]"
|
||||
},
|
||||
{
|
||||
"name": "cancelTakerTokenAmounts",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "batchCancelOrders",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderAddresses",
|
||||
"type": "address[5]"
|
||||
},
|
||||
{
|
||||
"name": "orderValues",
|
||||
"type": "uint256[6]"
|
||||
},
|
||||
{
|
||||
"name": "fillTakerTokenAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "shouldThrowOnInsufficientBalanceOrAllowance",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "v",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "r",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"name": "s",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "fillOrder",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "filledTakerTokenAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "orderAddresses",
|
||||
"type": "address[5]"
|
||||
},
|
||||
{
|
||||
"name": "orderValues",
|
||||
"type": "uint256[6]"
|
||||
}
|
||||
],
|
||||
"name": "getOrderHash",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "EXTERNAL_QUERY_GAS_LIMIT",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint16"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "VERSION",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_zrxToken",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenTransferProxy",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "maker",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "taker",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "feeRecipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "makerToken",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "takerToken",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "filledMakerTokenAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "filledTakerTokenAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "paidMakerFee",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "paidTakerFee",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "tokens",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "orderHash",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "LogFill",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "maker",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "feeRecipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "makerToken",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "takerToken",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "cancelledMakerTokenAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "cancelledTakerTokenAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "tokens",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "orderHash",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "LogCancel",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "errorId",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "orderHash",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "LogError",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0x12459c951127e0c374ff9105dda097662a027093"
|
||||
},
|
||||
"3": {
|
||||
"address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac"
|
||||
},
|
||||
"4": {
|
||||
"address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05"
|
||||
},
|
||||
"42": {
|
||||
"address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x48bacb9266a570d521063ef5dd96e61686dbe788"
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,172 +0,0 @@
|
||||
{
|
||||
"contract_name": "Token",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "supply",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "remaining",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,547 +0,0 @@
|
||||
{
|
||||
"contract_name": "TokenRegistry",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "removeToken",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getTokenAddressByName",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getTokenAddressBySymbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "setTokenSwarmHash",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getTokenMetaData",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "_ipfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "_swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "addToken",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "setTokenName",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "tokens",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "ipfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "tokenAddresses",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getTokenByName",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getTokenAddresses",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_ipfsHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "setTokenIpfsHash",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getTokenBySymbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "setTokenSymbol",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "ipfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogAddToken",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "ipfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogRemoveToken",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "oldName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newName",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "LogTokenNameChange",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "oldSymbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newSymbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "LogTokenSymbolChange",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "oldIpfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newIpfsHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogTokenIpfsHashChange",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "oldSwarmHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newSwarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogTokenSwarmHashChange",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c"
|
||||
},
|
||||
"3": {
|
||||
"address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed"
|
||||
},
|
||||
"4": {
|
||||
"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
|
||||
},
|
||||
"42": {
|
||||
"address": "0xf18e504561f4347bea557f3d4558f559dddbae7f"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082"
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,187 +0,0 @@
|
||||
{
|
||||
"contract_name": "TokenTransferProxy",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addAuthorizedAddress",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "authorities",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeAuthorizedAddress",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "authorized",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getAuthorizedAddresses",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "caller",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "LogAuthorizedAddressAdded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "caller",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "LogAuthorizedAddressRemoved",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
|
||||
},
|
||||
"3": {
|
||||
"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
|
||||
},
|
||||
"4": {
|
||||
"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
|
||||
},
|
||||
"42": {
|
||||
"address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"contract_name": "ZRX",
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
|
||||
},
|
||||
"3": {
|
||||
"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
|
||||
},
|
||||
"4": {
|
||||
"address": "0x00f58d6d585f84b2d7267940cede30ce2fe6eae8"
|
||||
},
|
||||
"42": {
|
||||
"address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,32 +1,38 @@
|
||||
export { ZeroEx } from './0x';
|
||||
|
||||
export { MessagePrefixType, MessagePrefixOpts } from '@0xproject/order-utils';
|
||||
export { Web3ProviderEngine, RPCSubprovider } from '@0xproject/subproviders';
|
||||
|
||||
export {
|
||||
BlockParamLiteral,
|
||||
FilterObject,
|
||||
BlockParam,
|
||||
ContractEventArg,
|
||||
ExchangeContractErrs,
|
||||
LogWithDecodedArgs,
|
||||
Order,
|
||||
Provider,
|
||||
SignedOrder,
|
||||
ECSignature,
|
||||
OrderStateValid,
|
||||
OrderStateInvalid,
|
||||
OrderState,
|
||||
Token,
|
||||
TransactionReceipt,
|
||||
TransactionReceiptWithDecodedLogs,
|
||||
ERC20AssetData,
|
||||
ERC721AssetData,
|
||||
AssetProxyId,
|
||||
} from '@0xproject/types';
|
||||
|
||||
export { OrderWatcherConfig } from '@0xproject/order-watcher';
|
||||
export {
|
||||
BlockParamLiteral,
|
||||
FilterObject,
|
||||
BlockParam,
|
||||
LogWithDecodedArgs,
|
||||
ContractEventArg,
|
||||
Provider,
|
||||
TransactionReceipt,
|
||||
TransactionReceiptWithDecodedLogs,
|
||||
} from 'ethereum-types';
|
||||
|
||||
export {
|
||||
EventCallback,
|
||||
ContractEvent,
|
||||
IndexedFilterValues,
|
||||
BlockRange,
|
||||
OrderCancellationRequest,
|
||||
OrderFillRequest,
|
||||
ContractEventArgs,
|
||||
MethodOpts,
|
||||
@@ -36,18 +42,25 @@ export {
|
||||
DecodedLogEvent,
|
||||
OnOrderStateChangeCallback,
|
||||
ContractWrappersError,
|
||||
EtherTokenContractEventArgs,
|
||||
WithdrawalContractEventArgs,
|
||||
DepositContractEventArgs,
|
||||
EtherTokenEvents,
|
||||
TransferContractEventArgs,
|
||||
ApprovalContractEventArgs,
|
||||
TokenContractEventArgs,
|
||||
TokenEvents,
|
||||
LogErrorContractEventArgs,
|
||||
LogCancelContractEventArgs,
|
||||
LogFillContractEventArgs,
|
||||
ExchangeContractEventArgs,
|
||||
ExchangeEvents,
|
||||
WETH9Events,
|
||||
WETH9WithdrawalEventArgs,
|
||||
WETH9ApprovalEventArgs,
|
||||
WETH9EventArgs,
|
||||
WETH9DepositEventArgs,
|
||||
WETH9TransferEventArgs,
|
||||
ERC20TokenTransferEventArgs,
|
||||
ERC20TokenApprovalEventArgs,
|
||||
ERC20TokenEvents,
|
||||
ERC20TokenEventArgs,
|
||||
ERC721TokenApprovalEventArgs,
|
||||
ERC721TokenApprovalForAllEventArgs,
|
||||
ERC721TokenTransferEventArgs,
|
||||
ERC721TokenEvents,
|
||||
ExchangeCancelUpToEventArgs,
|
||||
ExchangeAssetProxyRegisteredEventArgs,
|
||||
ExchangeFillEventArgs,
|
||||
ExchangeCancelEventArgs,
|
||||
ExchangeEventArgs,
|
||||
ContractWrappersConfig,
|
||||
OrderInfo,
|
||||
} from '@0xproject/contract-wrappers';
|
||||
|
@@ -8,8 +8,8 @@ export const zeroExPrivateNetworkConfigSchema = {
|
||||
gasPrice: { $ref: '/Number' },
|
||||
zrxContractAddress: { $ref: '/Address' },
|
||||
exchangeContractAddress: { $ref: '/Address' },
|
||||
tokenRegistryContractAddress: { $ref: '/Address' },
|
||||
tokenTransferProxyContractAddress: { $ref: '/Address' },
|
||||
erc20ProxyContractAddress: { $ref: '/Address' },
|
||||
erc721ProxyContractAddress: { $ref: '/Address' },
|
||||
orderWatcherConfig: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -29,7 +29,7 @@ export const zeroExPrivateNetworkConfigSchema = {
|
||||
'networkId',
|
||||
'zrxContractAddress',
|
||||
'exchangeContractAddress',
|
||||
'tokenRegistryContractAddress',
|
||||
'tokenTransferProxyContractAddress',
|
||||
'erc20ProxyContractAddress',
|
||||
'erc721ProxyContractAddress',
|
||||
],
|
||||
};
|
||||
|
@@ -22,8 +22,8 @@ export const zeroExPublicNetworkConfigSchema = {
|
||||
gasPrice: { $ref: '/Number' },
|
||||
zrxContractAddress: { $ref: '/Address' },
|
||||
exchangeContractAddress: { $ref: '/Address' },
|
||||
tokenRegistryContractAddress: { $ref: '/Address' },
|
||||
tokenTransferProxyContractAddress: { $ref: '/Address' },
|
||||
erc20ProxyContractAddress: { $ref: '/Address' },
|
||||
erc721ProxyContractAddress: { $ref: '/Address' },
|
||||
orderWatcherConfig: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
@@ -2,14 +2,13 @@ import { ContractWrappers } from '@0xproject/contract-wrappers';
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as _ from 'lodash';
|
||||
import 'mocha';
|
||||
|
||||
import { ApprovalContractEventArgs, LogWithDecodedArgs, TokenEvents, ZeroEx } from '../src';
|
||||
import { ERC20TokenApprovalEventArgs, ERC20TokenEvents, LogWithDecodedArgs, ZeroEx } from '../src';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { TokenUtils } from './utils/token_utils';
|
||||
import { tokenUtils } from './utils/token_utils';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
@@ -28,9 +27,7 @@ describe('ZeroEx library', () => {
|
||||
it('overrides provider in nested web3s and invalidates contractInstances', async () => {
|
||||
// Instantiate the contract instances with the current provider
|
||||
await (zeroEx.exchange as any)._getExchangeContractAsync();
|
||||
await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
|
||||
expect((zeroEx.exchange as any)._exchangeContractIfExists).to.not.be.undefined();
|
||||
expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.not.be.undefined();
|
||||
|
||||
// Add property to newProvider so that we can differentiate it from old provider
|
||||
(provider as any).zeroExTestId = 1;
|
||||
@@ -38,52 +35,43 @@ describe('ZeroEx library', () => {
|
||||
|
||||
// Check that contractInstances with old provider are removed after provider update
|
||||
expect((zeroEx.exchange as any)._exchangeContractIfExists).to.be.undefined();
|
||||
expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.be.undefined();
|
||||
|
||||
// Check that all nested zeroExContract/web3Wrapper instances return the updated provider
|
||||
const nestedWeb3WrapperProvider = ((zeroEx as any)._contractWrappers as ContractWrappers).getProvider();
|
||||
expect((nestedWeb3WrapperProvider as any).zeroExTestId).to.be.a('number');
|
||||
const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getProvider();
|
||||
expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
|
||||
const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getProvider();
|
||||
expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
|
||||
});
|
||||
});
|
||||
describe('#isValidSignature', () => {
|
||||
// The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes
|
||||
// the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size.
|
||||
const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
|
||||
const signature = {
|
||||
v: 27,
|
||||
r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
|
||||
s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
|
||||
};
|
||||
const ethSignSignature =
|
||||
'0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403';
|
||||
const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
|
||||
it("should return false if the data doesn't pertain to the signature & address", async () => {
|
||||
return expect(
|
||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
|
||||
).to.become(false);
|
||||
return expect((zeroEx.exchange as any).isValidSignatureAsync('0x0', address, ethSignSignature)).to.become(
|
||||
false,
|
||||
);
|
||||
});
|
||||
it("should return false if the address doesn't pertain to the signature & data", async () => {
|
||||
const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
|
||||
return expect(
|
||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
|
||||
dataHex,
|
||||
signature,
|
||||
validUnrelatedAddress,
|
||||
),
|
||||
(zeroEx.exchange as any).isValidSignatureAsync(dataHex, validUnrelatedAddress, ethSignSignature),
|
||||
).to.become(false);
|
||||
});
|
||||
it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
|
||||
const wrongSignature = _.assign({}, signature, { v: 28 });
|
||||
return expect(
|
||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
|
||||
).to.become(false);
|
||||
const signatureArray = ethSignSignature.split('');
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
signatureArray[5] = 'C'; // V = 28, instead of 27
|
||||
const wrongSignature = signatureArray.join('');
|
||||
return expect((zeroEx.exchange as any).isValidSignatureAsync(dataHex, address, wrongSignature)).to.become(
|
||||
false,
|
||||
);
|
||||
});
|
||||
it('should return true if the signature does pertain to the dataHex & address', async () => {
|
||||
return expect(
|
||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
|
||||
).to.become(true);
|
||||
return expect((zeroEx.exchange as any).isValidSignatureAsync(dataHex, address, ethSignSignature)).to.become(
|
||||
true,
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('#toUnitAmount', () => {
|
||||
@@ -128,18 +116,16 @@ describe('ZeroEx library', () => {
|
||||
it('returns transaction receipt with decoded logs', async () => {
|
||||
const availableAddresses = await zeroEx.getAvailableAddressesAsync();
|
||||
const coinbase = availableAddresses[0];
|
||||
const tokens = await zeroEx.tokenRegistry.getTokensAsync();
|
||||
const tokenUtils = new TokenUtils(tokens);
|
||||
const zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
|
||||
const proxyAddress = zeroEx.proxy.getContractAddress();
|
||||
const txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(zrxTokenAddress, coinbase);
|
||||
const zrxTokenAddress = tokenUtils.getProtocolTokenAddress();
|
||||
const erc20ProxyAddress = zeroEx.erc20Proxy.getContractAddress();
|
||||
const txHash = await zeroEx.erc20Token.setUnlimitedProxyAllowanceAsync(zrxTokenAddress, coinbase);
|
||||
const txReceiptWithDecodedLogs = await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const log = txReceiptWithDecodedLogs.logs[0] as LogWithDecodedArgs<ApprovalContractEventArgs>;
|
||||
expect(log.event).to.be.equal(TokenEvents.Approval);
|
||||
const log = txReceiptWithDecodedLogs.logs[0] as LogWithDecodedArgs<ERC20TokenApprovalEventArgs>;
|
||||
expect(log.event).to.be.equal(ERC20TokenEvents.Approval);
|
||||
expect(log.args._owner).to.be.equal(coinbase);
|
||||
expect(log.args._spender).to.be.equal(proxyAddress);
|
||||
expect(log.args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
|
||||
expect(log.args._spender).to.be.equal(erc20ProxyAddress);
|
||||
expect(log.args._value).to.be.bignumber.equal(zeroEx.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
|
||||
});
|
||||
});
|
||||
describe('#config', () => {
|
||||
@@ -151,15 +137,13 @@ describe('ZeroEx library', () => {
|
||||
const zeroExWithWrongExchangeAddress = new ZeroEx(provider, zeroExConfig);
|
||||
expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
|
||||
});
|
||||
it('allows to specify token registry token contract address', async () => {
|
||||
it('allows to specify erc20Proxy contract address', async () => {
|
||||
const zeroExConfig = {
|
||||
tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,
|
||||
erc20ProxyContractAddress: ZeroEx.NULL_ADDRESS,
|
||||
networkId: constants.TESTRPC_NETWORK_ID,
|
||||
};
|
||||
const zeroExWithWrongTokenRegistryAddress = new ZeroEx(provider, zeroExConfig);
|
||||
expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
|
||||
ZeroEx.NULL_ADDRESS,
|
||||
);
|
||||
const zeroExWithWrongERC20ProxyAddress = new ZeroEx(provider, zeroExConfig);
|
||||
expect(zeroExWithWrongERC20ProxyAddress.erc20Proxy.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,48 +0,0 @@
|
||||
import { web3Factory } from '@0xproject/dev-utils';
|
||||
|
||||
import { ZeroEx } from '../src';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
|
||||
chaiSetup.configure();
|
||||
|
||||
// Those tests are slower cause they're talking to a remote node
|
||||
const TIMEOUT = 10000;
|
||||
|
||||
describe('Artifacts', () => {
|
||||
describe('contracts are deployed on kovan', () => {
|
||||
const kovanRpcUrl = constants.KOVAN_RPC_URL;
|
||||
const provider = web3Factory.getRpcProvider({ rpcUrl: kovanRpcUrl });
|
||||
const config = {
|
||||
networkId: constants.KOVAN_NETWORK_ID,
|
||||
};
|
||||
const zeroEx = new ZeroEx(provider, config);
|
||||
it('token registry contract is deployed', async () => {
|
||||
await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
it('proxy contract is deployed', async () => {
|
||||
await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
it('exchange contract is deployed', async () => {
|
||||
await (zeroEx.exchange as any)._getExchangeContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
});
|
||||
describe('contracts are deployed on ropsten', () => {
|
||||
const ropstenRpcUrl = constants.ROPSTEN_RPC_URL;
|
||||
const provider = web3Factory.getRpcProvider({ rpcUrl: ropstenRpcUrl });
|
||||
const config = {
|
||||
networkId: constants.ROPSTEN_NETWORK_ID,
|
||||
};
|
||||
const zeroEx = new ZeroEx(provider, config);
|
||||
it('token registry contract is deployed', async () => {
|
||||
await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
it('proxy contract is deployed', async () => {
|
||||
await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
it('exchange contract is deployed', async () => {
|
||||
await (zeroEx.exchange as any)._getExchangeContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
});
|
||||
});
|
@@ -1,5 +1,5 @@
|
||||
import { devConstants } from '@0xproject/dev-utils';
|
||||
import { runV1MigrationsAsync } from '@0xproject/migrations';
|
||||
import { runV2MigrationsAsync } from '@0xproject/migrations';
|
||||
|
||||
import { provider } from './utils/web3_wrapper';
|
||||
|
||||
@@ -7,11 +7,11 @@ before('migrate contracts', async function(): Promise<void> {
|
||||
// HACK: Since the migrations take longer then our global mocha timeout limit
|
||||
// we manually increase it for this before hook.
|
||||
const mochaTestTimeoutMs = 20000;
|
||||
this.timeout(mochaTestTimeoutMs);
|
||||
this.timeout(mochaTestTimeoutMs); // tslint:disable-line:no-invalid-this
|
||||
const txDefaults = {
|
||||
gas: devConstants.GAS_LIMIT,
|
||||
from: devConstants.TESTRPC_FIRST_ADDRESS,
|
||||
};
|
||||
const artifactsDir = `../migrations/artifacts/1.0.0`;
|
||||
await runV1MigrationsAsync(provider, artifactsDir, txDefaults);
|
||||
const artifactsDir = `../migrations/artifacts/2.0.0`;
|
||||
await runV2MigrationsAsync(provider, artifactsDir, txDefaults);
|
||||
});
|
||||
|
@@ -1,34 +1,9 @@
|
||||
import { Token } from '@0xproject/types';
|
||||
import * as _ from 'lodash';
|
||||
import { artifacts } from '../../src/artifacts';
|
||||
|
||||
import { InternalZeroExError } from '../../src/types';
|
||||
import { constants } from './constants';
|
||||
|
||||
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
|
||||
const WETH_TOKEN_SYMBOL = 'WETH';
|
||||
|
||||
export class TokenUtils {
|
||||
private _tokens: Token[];
|
||||
constructor(tokens: Token[]) {
|
||||
this._tokens = tokens;
|
||||
}
|
||||
public getProtocolTokenOrThrow(): Token {
|
||||
const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
|
||||
if (_.isUndefined(zrxToken)) {
|
||||
throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
|
||||
}
|
||||
return zrxToken;
|
||||
}
|
||||
public getWethTokenOrThrow(): Token {
|
||||
const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
|
||||
if (_.isUndefined(wethToken)) {
|
||||
throw new Error(InternalZeroExError.WethNotInTokenRegistry);
|
||||
}
|
||||
return wethToken;
|
||||
}
|
||||
public getDummyTokens(): Token[] {
|
||||
const dummyTokens = _.filter(this._tokens, token => {
|
||||
return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
|
||||
});
|
||||
return dummyTokens;
|
||||
}
|
||||
}
|
||||
export const tokenUtils = {
|
||||
getProtocolTokenAddress(): string {
|
||||
return artifacts.ZRXToken.networks[constants.TESTRPC_NETWORK_ID].address;
|
||||
},
|
||||
};
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import { web3Factory } from '@0xproject/dev-utils';
|
||||
import { Provider } from '@0xproject/types';
|
||||
import { devConstants, web3Factory } from '@0xproject/dev-utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
|
||||
const txDefaults = {
|
||||
from: devConstants.TESTRPC_FIRST_ADDRESS,
|
||||
gas: devConstants.GAS_LIMIT,
|
||||
};
|
||||
const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true });
|
||||
const web3Wrapper = new Web3Wrapper(provider);
|
||||
|
||||
export { provider, web3Wrapper };
|
||||
export { provider, web3Wrapper, txDefaults };
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"version": "0.4.0",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Convert e_r_c to erc in generated file names",
|
||||
@@ -9,6 +9,28 @@
|
||||
{
|
||||
"note": "Remove the output directory before writing to it",
|
||||
"pr": 822
|
||||
},
|
||||
{
|
||||
"note": "skip generation of wrappers that are already up to date",
|
||||
"pr": 788
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531919263,
|
||||
"version": "0.3.4",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531149657,
|
||||
"version": "0.3.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.3.4 - _July 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.3.3 - _July 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.3.2 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,2 +1,2 @@
|
||||
#!/usr/bin/env node
|
||||
require('../lib/index.js')
|
||||
require('../lib/src/index.js')
|
||||
|
0
packages/abi-gen/coverage/.gitkeep
Normal file
0
packages/abi-gen/coverage/.gitkeep
Normal file
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/abi-gen",
|
||||
"version": "0.3.2",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -12,6 +12,11 @@
|
||||
"lint": "tslint --project .",
|
||||
"clean": "shx rm -rf lib scripts",
|
||||
"build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
|
||||
"test": "yarn run_mocha",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --bail --exit",
|
||||
"test:circleci": "yarn test:coverage",
|
||||
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
|
||||
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
|
||||
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
|
||||
},
|
||||
"bin": {
|
||||
@@ -27,32 +32,37 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
|
||||
"dependencies": {
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"ethereum-types": "^0.0.2",
|
||||
"@0xproject/typescript-typings": "^1.0.0",
|
||||
"@0xproject/utils": "^1.0.0",
|
||||
"chalk": "^2.3.0",
|
||||
"ethereum-types": "^1.0.0",
|
||||
"glob": "^7.1.2",
|
||||
"handlebars": "^4.0.11",
|
||||
"lodash": "^4.17.4",
|
||||
"rimraf": "^2.6.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
"sleep": "^5.1.1",
|
||||
"tmp": "^0.0.33",
|
||||
"to-snake-case": "^1.0.0",
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@types/glob": "^5.0.33",
|
||||
"@types/rimraf": "^2.0.2",
|
||||
"@0xproject/monorepo-script": "^1.0.0",
|
||||
"@0xproject/tslint-config": "^1.0.0",
|
||||
"@types/glob": "5.0.35",
|
||||
"@types/handlebars": "^4.0.36",
|
||||
"@types/mkdirp": "^0.5.1",
|
||||
"@types/node": "^8.0.53",
|
||||
"@types/sleep": "^0.0.7",
|
||||
"@types/tmp": "^0.0.33",
|
||||
"@types/yargs": "^10.0.0",
|
||||
"chai": "^4.1.2",
|
||||
"copyfiles": "^1.2.0",
|
||||
"dirty-chai": "^2.0.1",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
"mocha": "^5.2.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"shx": "^0.2.2",
|
||||
"tslint": "5.8.0",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -3,16 +3,12 @@
|
||||
import { abiUtils, logUtils } from '@0xproject/utils';
|
||||
import chalk from 'chalk';
|
||||
import { AbiDefinition, ConstructorAbi, EventAbi, MethodAbi } from 'ethereum-types';
|
||||
import * as fs from 'fs';
|
||||
import { sync as globSync } from 'glob';
|
||||
import * as Handlebars from 'handlebars';
|
||||
import * as _ from 'lodash';
|
||||
import * as mkdirp from 'mkdirp';
|
||||
import * as rimraf from 'rimraf';
|
||||
import * as yargs from 'yargs';
|
||||
|
||||
import toSnakeCase = require('to-snake-case');
|
||||
|
||||
import { ContextData, ContractsBackend, ParamKind } from './types';
|
||||
import { utils } from './utils';
|
||||
|
||||
@@ -71,16 +67,6 @@ function registerPartials(partialsGlob: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
function writeOutputFile(name: string, renderedTsCode: string): void {
|
||||
let fileName = toSnakeCase(name);
|
||||
// HACK: Snake case doesn't make a lot of sense for abbreviated names but we can't reliably detect abbreviations
|
||||
// so we special-case the abbreviations we use.
|
||||
fileName = fileName.replace('z_r_x', 'zrx').replace('e_r_c', 'erc');
|
||||
const filePath = `${args.output}/${fileName}.ts`;
|
||||
fs.writeFileSync(filePath, renderedTsCode);
|
||||
logUtils.log(`Created: ${chalk.bold(filePath)}`);
|
||||
}
|
||||
|
||||
Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend));
|
||||
Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend));
|
||||
if (args.partials) {
|
||||
@@ -97,7 +83,6 @@ if (_.isEmpty(abiFileNames)) {
|
||||
process.exit(1);
|
||||
} else {
|
||||
logUtils.log(`Found ${chalk.green(`${abiFileNames.length}`)} ${chalk.bold('ABI')} files`);
|
||||
rimraf.sync(args.output);
|
||||
mkdirp.sync(args.output);
|
||||
}
|
||||
for (const abiFileName of abiFileNames) {
|
||||
@@ -120,6 +105,14 @@ for (const abiFileName of abiFileNames) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const outFileName = utils.makeOutputFileName(namedContent.name);
|
||||
const outFilePath = `${args.output}/${outFileName}.ts`;
|
||||
|
||||
if (utils.isOutputFileUpToDate(abiFileName, outFilePath)) {
|
||||
logUtils.log(`Aready up to date: ${chalk.bold(outFilePath)}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
let ctor = ABI.find((abi: AbiDefinition) => abi.type === ABI_TYPE_CONSTRUCTOR) as ConstructorAbi;
|
||||
if (_.isUndefined(ctor)) {
|
||||
ctor = utils.getEmptyConstructor(); // The constructor exists, but it's implicit in JSON's ABI definition
|
||||
@@ -154,5 +147,6 @@ for (const abiFileName of abiFileNames) {
|
||||
events: eventAbis,
|
||||
};
|
||||
const renderedTsCode = template(contextData);
|
||||
writeOutputFile(namedContent.name, renderedTsCode);
|
||||
utils.writeOutputFile(outFilePath, renderedTsCode);
|
||||
logUtils.log(`Created: ${chalk.bold(outFilePath)}`);
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ import { AbiType, ConstructorAbi, DataItem } from 'ethereum-types';
|
||||
import * as fs from 'fs';
|
||||
import * as _ from 'lodash';
|
||||
import * as path from 'path';
|
||||
import toSnakeCase = require('to-snake-case');
|
||||
|
||||
import { ContractsBackend, ParamKind } from './types';
|
||||
|
||||
@@ -92,4 +93,27 @@ export const utils = {
|
||||
inputs: [],
|
||||
};
|
||||
},
|
||||
makeOutputFileName(name: string): string {
|
||||
let fileName = toSnakeCase(name);
|
||||
// HACK: Snake case doesn't make a lot of sense for abbreviated names but we can't reliably detect abbreviations
|
||||
// so we special-case the abbreviations we use.
|
||||
fileName = fileName.replace('z_r_x', 'zrx').replace('e_r_c', 'erc');
|
||||
return fileName;
|
||||
},
|
||||
writeOutputFile(filePath: string, renderedTsCode: string): void {
|
||||
fs.writeFileSync(filePath, renderedTsCode);
|
||||
},
|
||||
isOutputFileUpToDate(abiFile: string, outputFile: string): boolean {
|
||||
const abiFileModTimeMs = fs.statSync(abiFile).mtimeMs;
|
||||
try {
|
||||
const outFileModTimeMs = fs.statSync(outputFile).mtimeMs;
|
||||
return outFileModTimeMs > abiFileModTimeMs;
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return false;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
86
packages/abi-gen/test/utils_test.ts
Normal file
86
packages/abi-gen/test/utils_test.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import * as chai from 'chai';
|
||||
import * as dirtyChai from 'dirty-chai';
|
||||
import * as fs from 'fs';
|
||||
import 'mocha';
|
||||
import * as tmp from 'tmp';
|
||||
|
||||
import { utils } from '../src/utils';
|
||||
|
||||
tmp.setGracefulCleanup(); // remove tmp files even if there are failures
|
||||
|
||||
chai.use(dirtyChai);
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
describe('makeOutputFileName()', () => {
|
||||
it('should handle Metacoin usage', () => {
|
||||
expect(utils.makeOutputFileName('Metacoin')).to.equal('metacoin');
|
||||
});
|
||||
it('should handle special zrx_token case', () => {
|
||||
expect(utils.makeOutputFileName('ZRXToken')).to.equal('zrx_token');
|
||||
});
|
||||
it('should handle special erc_token case', () => {
|
||||
expect(utils.makeOutputFileName('ERC20Token')).to.equal('erc20_token');
|
||||
});
|
||||
});
|
||||
|
||||
describe('writeOutputFile()', () => {
|
||||
let tempFilePath: string;
|
||||
before(() => {
|
||||
tempFilePath = tmp.fileSync(
|
||||
{ discardDescriptor: true }, // close file (so we can update it)
|
||||
).name;
|
||||
});
|
||||
it('should write content to output file', () => {
|
||||
const content = 'hello world';
|
||||
|
||||
utils.writeOutputFile(tempFilePath, content);
|
||||
|
||||
expect(fs.readFileSync(tempFilePath).toString()).to.equal(content);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isOutputFileUpToDate()', () => {
|
||||
it('should throw ENOENT when there is no abi file', () => {
|
||||
expect(utils.isOutputFileUpToDate.bind('nonexistant1', 'nonexistant2')).to.throw('ENOENT');
|
||||
});
|
||||
|
||||
describe('when the abi input file exists', () => {
|
||||
let abiFile: string;
|
||||
before(() => {
|
||||
abiFile = tmp.fileSync(
|
||||
{ discardDescriptor: true }, // close file (set timestamp)
|
||||
).name;
|
||||
});
|
||||
|
||||
describe('without an existing output file', () => {
|
||||
it('should return false', () => {
|
||||
expect(utils.isOutputFileUpToDate(abiFile, 'nonexistant_file')).to.be.false();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with an existing output file', () => {
|
||||
let outputFile: string;
|
||||
before(() => {
|
||||
outputFile = tmp.fileSync(
|
||||
{ discardDescriptor: true }, // close file (set timestamp)
|
||||
).name;
|
||||
const abiFileModTimeMs = fs.statSync(abiFile).mtimeMs;
|
||||
const outfileModTimeMs = abiFileModTimeMs + 1;
|
||||
fs.utimesSync(outputFile, outfileModTimeMs, outfileModTimeMs);
|
||||
});
|
||||
|
||||
it('should return true when output file is newer than abi file', async () => {
|
||||
expect(utils.isOutputFileUpToDate(abiFile, outputFile)).to.be.true();
|
||||
});
|
||||
|
||||
it('should return false when output file exists but is older than abi file', () => {
|
||||
const outFileModTimeMs = fs.statSync(outputFile).mtimeMs;
|
||||
const abiFileModTimeMs = outFileModTimeMs + 1;
|
||||
fs.utimesSync(abiFile, abiFileModTimeMs, abiFileModTimeMs);
|
||||
|
||||
expect(utils.isOutputFileUpToDate(abiFile, outputFile)).to.be.false();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"version": "0.2.13",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note":
|
||||
@@ -9,6 +9,24 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531919263,
|
||||
"version": "0.2.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531149657,
|
||||
"version": "0.2.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1529397769,
|
||||
"version": "0.2.12",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.2.14 - _July 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.2.13 - _July 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.2.12 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/assert",
|
||||
"version": "0.3.0",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -31,8 +31,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@0xproject/monorepo-script": "^1.0.0",
|
||||
"@0xproject/tslint-config": "^1.0.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/valid-url": "^1.0.2",
|
||||
@@ -44,13 +44,13 @@
|
||||
"npm-run-all": "^4.1.2",
|
||||
"nyc": "^11.0.1",
|
||||
"shx": "^0.2.2",
|
||||
"tslint": "5.8.0",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/json-schemas": "^1.0.0",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"@0xproject/json-schemas": "^1.0.0-rc.1",
|
||||
"@0xproject/typescript-typings": "^1.0.0",
|
||||
"@0xproject/utils": "^1.0.0",
|
||||
"lodash": "^4.17.4",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
|
@@ -8,33 +8,33 @@ const HEX_REGEX = /^0x[0-9A-F]*$/i;
|
||||
export const assert = {
|
||||
isBigNumber(variableName: string, value: BigNumber): void {
|
||||
const isBigNumber = _.isObject(value) && (value as any).isBigNumber;
|
||||
this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value));
|
||||
assert.assert(isBigNumber, assert.typeAssertionMessage(variableName, 'BigNumber', value));
|
||||
},
|
||||
isValidBaseUnitAmount(variableName: string, value: BigNumber): void {
|
||||
assert.isBigNumber(variableName, value);
|
||||
const isNegative = value.lessThan(0);
|
||||
this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
|
||||
assert.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
|
||||
const hasDecimals = value.decimalPlaces() !== 0;
|
||||
this.assert(
|
||||
assert.assert(
|
||||
!hasDecimals,
|
||||
`${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
|
||||
);
|
||||
},
|
||||
isString(variableName: string, value: string): void {
|
||||
this.assert(_.isString(value), this.typeAssertionMessage(variableName, 'string', value));
|
||||
assert.assert(_.isString(value), assert.typeAssertionMessage(variableName, 'string', value));
|
||||
},
|
||||
isFunction(variableName: string, value: any): void {
|
||||
this.assert(_.isFunction(value), this.typeAssertionMessage(variableName, 'function', value));
|
||||
assert.assert(_.isFunction(value), assert.typeAssertionMessage(variableName, 'function', value));
|
||||
},
|
||||
isHexString(variableName: string, value: string): void {
|
||||
this.assert(
|
||||
assert.assert(
|
||||
_.isString(value) && HEX_REGEX.test(value),
|
||||
this.typeAssertionMessage(variableName, 'HexString', value),
|
||||
assert.typeAssertionMessage(variableName, 'HexString', value),
|
||||
);
|
||||
},
|
||||
isETHAddressHex(variableName: string, value: string): void {
|
||||
this.assert(_.isString(value), this.typeAssertionMessage(variableName, 'string', value));
|
||||
this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
|
||||
assert.assert(_.isString(value), assert.typeAssertionMessage(variableName, 'string', value));
|
||||
assert.assert(addressUtils.isAddress(value), assert.typeAssertionMessage(variableName, 'ETHAddressHex', value));
|
||||
},
|
||||
doesBelongToStringEnum(
|
||||
variableName: string,
|
||||
@@ -51,17 +51,17 @@ export const assert = {
|
||||
);
|
||||
},
|
||||
hasAtMostOneUniqueValue(value: any[], errMsg: string): void {
|
||||
this.assert(_.uniq(value).length <= 1, errMsg);
|
||||
assert.assert(_.uniq(value).length <= 1, errMsg);
|
||||
},
|
||||
isNumber(variableName: string, value: number): void {
|
||||
this.assert(_.isFinite(value), this.typeAssertionMessage(variableName, 'number', value));
|
||||
assert.assert(_.isFinite(value), assert.typeAssertionMessage(variableName, 'number', value));
|
||||
},
|
||||
isBoolean(variableName: string, value: boolean): void {
|
||||
this.assert(_.isBoolean(value), this.typeAssertionMessage(variableName, 'boolean', value));
|
||||
assert.assert(_.isBoolean(value), assert.typeAssertionMessage(variableName, 'boolean', value));
|
||||
},
|
||||
isWeb3Provider(variableName: string, value: any): void {
|
||||
const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync);
|
||||
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Provider', value));
|
||||
assert.assert(isWeb3Provider, assert.typeAssertionMessage(variableName, 'Provider', value));
|
||||
},
|
||||
doesConformToSchema(variableName: string, value: any, schema: Schema, subSchemas?: Schema[]): void {
|
||||
if (_.isUndefined(value)) {
|
||||
@@ -76,15 +76,15 @@ export const assert = {
|
||||
const msg = `Expected ${variableName} to conform to schema ${schema.id}
|
||||
Encountered: ${JSON.stringify(value, null, '\t')}
|
||||
Validation errors: ${validationResult.errors.join(', ')}`;
|
||||
this.assert(!hasValidationErrors, msg);
|
||||
assert.assert(!hasValidationErrors, msg);
|
||||
},
|
||||
isWebUri(variableName: string, value: any): void {
|
||||
const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
|
||||
this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'web uri', value));
|
||||
assert.assert(isValidUrl, assert.typeAssertionMessage(variableName, 'web uri', value));
|
||||
},
|
||||
isUri(variableName: string, value: any): void {
|
||||
const isValidUri = !_.isUndefined(validUrl.isUri(value));
|
||||
this.assert(isValidUri, this.typeAssertionMessage(variableName, 'uri', value));
|
||||
assert.assert(isValidUri, assert.typeAssertionMessage(variableName, 'uri', value));
|
||||
},
|
||||
assert(condition: boolean, message: string): void {
|
||||
if (!condition) {
|
||||
|
@@ -49,7 +49,7 @@ describe('Assertions', () => {
|
||||
});
|
||||
describe('#isFunction', () => {
|
||||
it('should not throw for valid input', () => {
|
||||
const validInputs = [BigNumber, assert.isString];
|
||||
const validInputs = [BigNumber, assert.isString.bind(assert)];
|
||||
validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
|
||||
});
|
||||
it('should throw for invalid input', () => {
|
||||
|
@@ -1,4 +1,30 @@
|
||||
[
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531919263,
|
||||
"version": "0.3.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531149657,
|
||||
"version": "0.3.5",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "0.3.4",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.3.6 - _July 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.3.5 - _July 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.3.4 - _June 19, 2018_
|
||||
|
||||
* Update EthersJs to fix the `value.toLowerCase()` is not a function bug caused by `ethers.js` breaking patch version https://github.com/ethers-io/ethers.js/issues/201
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/base-contract",
|
||||
"version": "0.3.4",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -9,7 +9,7 @@
|
||||
"types": "lib/src/index.d.ts",
|
||||
"scripts": {
|
||||
"watch_without_deps": "tsc -w",
|
||||
"build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
|
||||
"build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
|
||||
"clean": "shx rm -rf lib scripts",
|
||||
"test": "yarn run_mocha",
|
||||
"rebuild_and_test": "run-s clean build test",
|
||||
@@ -30,8 +30,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@0xproject/monorepo-script": "^1.0.0",
|
||||
"@0xproject/tslint-config": "^1.0.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
"chai": "^4.0.1",
|
||||
"copyfiles": "^1.2.0",
|
||||
@@ -39,14 +39,14 @@
|
||||
"mocha": "^4.0.1",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"shx": "^0.2.2",
|
||||
"tslint": "5.8.0",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ethereum-types": "^0.0.2",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"@0xproject/web3-wrapper": "^0.7.1",
|
||||
"ethereum-types": "^1.0.0",
|
||||
"@0xproject/typescript-typings": "^1.0.0",
|
||||
"@0xproject/utils": "^1.0.0",
|
||||
"@0xproject/web3-wrapper": "^1.0.0",
|
||||
"ethers": "3.0.22",
|
||||
"lodash": "^4.17.4"
|
||||
},
|
||||
|
@@ -72,15 +72,13 @@ export class BaseContract {
|
||||
// 1. Optional param passed in to public method call
|
||||
// 2. Global config passed in at library instantiation
|
||||
// 3. Gas estimate calculation + safety margin
|
||||
const removeUndefinedProperties = _.pickBy;
|
||||
const txDataWithDefaults: TxData = {
|
||||
const removeUndefinedProperties = _.pickBy.bind(_);
|
||||
const txDataWithDefaults = {
|
||||
...removeUndefinedProperties(txDefaults),
|
||||
...removeUndefinedProperties(txData as any),
|
||||
// HACK: TS can't prove that T is spreadable.
|
||||
// Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged
|
||||
} as any;
|
||||
...removeUndefinedProperties(txData),
|
||||
};
|
||||
if (_.isUndefined(txDataWithDefaults.gas) && !_.isUndefined(estimateGasAsync)) {
|
||||
txDataWithDefaults.gas = await estimateGasAsync(txDataWithDefaults as any);
|
||||
txDataWithDefaults.gas = await estimateGasAsync(txDataWithDefaults);
|
||||
}
|
||||
return txDataWithDefaults;
|
||||
}
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note":
|
||||
"Remove WebSocketOrderbookChannel from the public interface and replace with orderbookChannelFactory"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531919263,
|
||||
"version": "0.6.17",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1531149657,
|
||||
"version": "0.6.16",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1529397769,
|
||||
"version": "0.6.15",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.6.17 - _July 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.6.16 - _July 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.6.15 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/connect",
|
||||
"version": "0.6.15",
|
||||
"version": "0.6.17",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -51,24 +51,25 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
|
||||
"dependencies": {
|
||||
"@0xproject/assert": "^0.2.12",
|
||||
"@0xproject/json-schemas": "0.8.1",
|
||||
"@0xproject/types": "^0.8.1",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"isomorphic-fetch": "^2.2.1",
|
||||
"@0xproject/assert": "^1.0.0",
|
||||
"@0xproject/json-schemas": "^1.0.0-rc.1",
|
||||
"@0xproject/types": "^1.0.0-rc.1",
|
||||
"@0xproject/typescript-typings": "^1.0.0",
|
||||
"@0xproject/utils": "^1.0.0",
|
||||
"lodash": "^4.17.4",
|
||||
"query-string": "^5.0.1",
|
||||
"sinon": "^4.0.0",
|
||||
"websocket": "^1.0.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@types/fetch-mock": "^5.12.1",
|
||||
"@0xproject/monorepo-script": "^1.0.0",
|
||||
"@0xproject/tslint-config": "^1.0.0",
|
||||
"@types/fetch-mock": "^5.12.2",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/query-string": "^5.0.1",
|
||||
"@types/websocket": "^0.0.34",
|
||||
"@types/sinon": "^2.2.2",
|
||||
"@types/websocket": "^0.0.39",
|
||||
"async-child-process": "^1.1.1",
|
||||
"chai": "^4.0.1",
|
||||
"chai-as-promised": "^7.1.0",
|
||||
@@ -80,7 +81,7 @@
|
||||
"npm-run-all": "^4.1.2",
|
||||
"nyc": "^11.0.1",
|
||||
"shx": "^0.2.2",
|
||||
"tslint": "5.8.0",
|
||||
"tslint": "5.11.0",
|
||||
"typedoc": "~0.8.0",
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { assert } from '@0xproject/assert';
|
||||
import { schemas } from '@0xproject/json-schemas';
|
||||
import { SignedOrder } from '@0xproject/types';
|
||||
import 'isomorphic-fetch';
|
||||
import { fetchAsync } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
import * as queryString from 'query-string';
|
||||
|
||||
@@ -38,7 +38,7 @@ const OPTS_TO_QUERY_FIELD_MAP = {
|
||||
* that implement the standard relayer API v0
|
||||
*/
|
||||
export class HttpClient implements Client {
|
||||
private _apiEndpointUrl: string;
|
||||
private readonly _apiEndpointUrl: string;
|
||||
/**
|
||||
* Format parameters to be appended to http requests into query string form
|
||||
*/
|
||||
@@ -167,7 +167,7 @@ export class HttpClient implements Client {
|
||||
const headers = new Headers({
|
||||
'content-type': 'application/json',
|
||||
});
|
||||
const response = await fetch(url, {
|
||||
const response = await fetchAsync(url, {
|
||||
method: requestType,
|
||||
body: JSON.stringify(payload),
|
||||
headers,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
export { HttpClient } from './http_client';
|
||||
export { WebSocketOrderbookChannel } from './ws_orderbook_channel';
|
||||
export { orderbookChannelFactory } from './orderbook_channel_factory';
|
||||
export {
|
||||
Client,
|
||||
FeesRequest,
|
||||
@@ -14,7 +14,6 @@ export {
|
||||
TokenPairsItem,
|
||||
TokenPairsRequestOpts,
|
||||
TokenTradeInfo,
|
||||
WebSocketOrderbookChannelConfig,
|
||||
} from './types';
|
||||
|
||||
export { Order, SignedOrder } from '@0xproject/types';
|
||||
|
32
packages/connect/src/orderbook_channel_factory.ts
Normal file
32
packages/connect/src/orderbook_channel_factory.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import * as WebSocket from 'websocket';
|
||||
|
||||
import { OrderbookChannel, OrderbookChannelHandler } from './types';
|
||||
import { assert } from './utils/assert';
|
||||
import { WebSocketOrderbookChannel } from './ws_orderbook_channel';
|
||||
|
||||
export const orderbookChannelFactory = {
|
||||
/**
|
||||
* Instantiates a new WebSocketOrderbookChannel instance
|
||||
* @param url The relayer API base WS url you would like to interact with
|
||||
* @param handler An OrderbookChannelHandler instance that responds to various
|
||||
* channel updates
|
||||
* @return An OrderbookChannel Promise
|
||||
*/
|
||||
async createWebSocketOrderbookChannelAsync(
|
||||
url: string,
|
||||
handler: OrderbookChannelHandler,
|
||||
): Promise<OrderbookChannel> {
|
||||
assert.isUri('url', url);
|
||||
assert.isOrderbookChannelHandler('handler', handler);
|
||||
return new Promise<OrderbookChannel>((resolve, reject) => {
|
||||
const client = new WebSocket.w3cwebsocket(url);
|
||||
client.onopen = () => {
|
||||
const orderbookChannel = new WebSocketOrderbookChannel(client, handler);
|
||||
resolve(orderbookChannel);
|
||||
};
|
||||
client.onerror = err => {
|
||||
reject(err);
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
@@ -3,7 +3,6 @@ import { orderBookRequestSchema } from './orderbook_request_schema';
|
||||
import { ordersRequestOptsSchema } from './orders_request_opts_schema';
|
||||
import { pagedRequestOptsSchema } from './paged_request_opts_schema';
|
||||
import { tokenPairsRequestOptsSchema } from './token_pairs_request_opts_schema';
|
||||
import { webSocketOrderbookChannelConfigSchema } from './websocket_orderbook_channel_config_schema';
|
||||
|
||||
export const schemas = {
|
||||
feesRequestSchema,
|
||||
@@ -11,5 +10,4 @@ export const schemas = {
|
||||
ordersRequestOptsSchema,
|
||||
pagedRequestOptsSchema,
|
||||
tokenPairsRequestOptsSchema,
|
||||
webSocketOrderbookChannelConfigSchema,
|
||||
};
|
||||
|
@@ -1,10 +0,0 @@
|
||||
export const webSocketOrderbookChannelConfigSchema = {
|
||||
id: '/WebSocketOrderbookChannelConfig',
|
||||
type: 'object',
|
||||
properties: {
|
||||
heartbeatIntervalMs: {
|
||||
type: 'number',
|
||||
minimum: 10,
|
||||
},
|
||||
},
|
||||
};
|
@@ -11,17 +11,10 @@ export interface Client {
|
||||
}
|
||||
|
||||
export interface OrderbookChannel {
|
||||
subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler) => void;
|
||||
subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
|
||||
close: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* heartbeatInterval: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000
|
||||
*/
|
||||
export interface WebSocketOrderbookChannelConfig {
|
||||
heartbeatIntervalMs?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* baseTokenAddress: The address of token designated as the baseToken in the currency pair calculation of price
|
||||
* quoteTokenAddress: The address of token designated as the quoteToken in the currency pair calculation of price
|
||||
@@ -46,8 +39,8 @@ export interface OrderbookChannelHandler {
|
||||
subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
||||
order: SignedOrder,
|
||||
) => void;
|
||||
onError: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts, err: Error) => void;
|
||||
onClose: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
|
||||
onError: (channel: OrderbookChannel, err: Error, subscriptionOpts?: OrderbookChannelSubscriptionOpts) => void;
|
||||
onClose: (channel: OrderbookChannel) => void;
|
||||
}
|
||||
|
||||
export type OrderbookChannelMessage =
|
||||
|
26
packages/connect/src/utils/assert.ts
Normal file
26
packages/connect/src/utils/assert.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { assert as sharedAssert } from '@0xproject/assert';
|
||||
// HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
import { Schema, schemas } from '@0xproject/json-schemas';
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
import { ECSignature } from '@0xproject/types';
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
export const assert = {
|
||||
...sharedAssert,
|
||||
isOrderbookChannelSubscriptionOpts(variableName: string, subscriptionOpts: any): void {
|
||||
sharedAssert.doesConformToSchema(
|
||||
variableName,
|
||||
subscriptionOpts,
|
||||
schemas.relayerApiOrderbookChannelSubscribePayload,
|
||||
);
|
||||
},
|
||||
isOrderbookChannelHandler(variableName: string, handler: any): void {
|
||||
sharedAssert.isFunction(`${variableName}.onSnapshot`, _.get(handler, 'onSnapshot'));
|
||||
sharedAssert.isFunction(`${variableName}.onUpdate`, _.get(handler, 'onUpdate'));
|
||||
sharedAssert.isFunction(`${variableName}.onError`, _.get(handler, 'onError'));
|
||||
sharedAssert.isFunction(`${variableName}.onClose`, _.get(handler, 'onClose'));
|
||||
},
|
||||
};
|
@@ -8,10 +8,16 @@ import { relayerResponseJsonParsers } from './relayer_response_json_parsers';
|
||||
|
||||
export const orderbookChannelMessageParser = {
|
||||
parse(utf8Data: string): OrderbookChannelMessage {
|
||||
// parse the message
|
||||
const messageObj = JSON.parse(utf8Data);
|
||||
// ensure we have a type parameter to switch on
|
||||
const type: string = _.get(messageObj, 'type');
|
||||
assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
|
||||
assert.isString('type', type);
|
||||
// ensure we have a request id for the resulting message
|
||||
const requestId: number = _.get(messageObj, 'requestId');
|
||||
assert.assert(!_.isUndefined(requestId), `Message is missing a requestId parameter: ${utf8Data}`);
|
||||
assert.isNumber('requestId', requestId);
|
||||
switch (type) {
|
||||
case OrderbookChannelMessageTypes.Snapshot: {
|
||||
assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
|
||||
@@ -28,7 +34,7 @@ export const orderbookChannelMessageParser = {
|
||||
default: {
|
||||
return {
|
||||
type: OrderbookChannelMessageTypes.Unknown,
|
||||
requestId: 0,
|
||||
requestId,
|
||||
payload: undefined,
|
||||
};
|
||||
}
|
||||
|
@@ -6,12 +6,12 @@ export const typeConverters = {
|
||||
const bids = _.get(orderbook, 'bids', []);
|
||||
const asks = _.get(orderbook, 'asks', []);
|
||||
return {
|
||||
bids: bids.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
|
||||
asks: asks.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
|
||||
bids: bids.map((order: any) => typeConverters.convertOrderStringFieldsToBigNumber(order)),
|
||||
asks: asks.map((order: any) => typeConverters.convertOrderStringFieldsToBigNumber(order)),
|
||||
};
|
||||
},
|
||||
convertOrderStringFieldsToBigNumber(order: any): any {
|
||||
return this.convertStringsFieldsToBigNumbers(order, [
|
||||
return typeConverters.convertStringsFieldsToBigNumbers(order, [
|
||||
'makerTokenAmount',
|
||||
'takerTokenAmount',
|
||||
'makerFee',
|
||||
|
@@ -1,166 +1,105 @@
|
||||
import { assert } from '@0xproject/assert';
|
||||
import { schemas } from '@0xproject/json-schemas';
|
||||
import * as _ from 'lodash';
|
||||
import * as WebSocket from 'websocket';
|
||||
|
||||
import { schemas as clientSchemas } from './schemas/schemas';
|
||||
import {
|
||||
OrderbookChannel,
|
||||
OrderbookChannelHandler,
|
||||
OrderbookChannelMessageTypes,
|
||||
OrderbookChannelSubscriptionOpts,
|
||||
WebsocketClientEventType,
|
||||
WebsocketConnectionEventType,
|
||||
WebSocketOrderbookChannelConfig,
|
||||
} from './types';
|
||||
import { assert } from './utils/assert';
|
||||
import { orderbookChannelMessageParser } from './utils/orderbook_channel_message_parser';
|
||||
|
||||
const DEFAULT_HEARTBEAT_INTERVAL_MS = 15000;
|
||||
const MINIMUM_HEARTBEAT_INTERVAL_MS = 10;
|
||||
|
||||
/**
|
||||
* This class includes all the functionality related to interacting with a websocket endpoint
|
||||
* that implements the standard relayer API v0
|
||||
*/
|
||||
export class WebSocketOrderbookChannel implements OrderbookChannel {
|
||||
private _apiEndpointUrl: string;
|
||||
private _client: WebSocket.client;
|
||||
private _connectionIfExists?: WebSocket.connection;
|
||||
private _heartbeatTimerIfExists?: NodeJS.Timer;
|
||||
private _subscriptionCounter = 0;
|
||||
private _heartbeatIntervalMs: number;
|
||||
private readonly _client: WebSocket.w3cwebsocket;
|
||||
private readonly _handler: OrderbookChannelHandler;
|
||||
private readonly _subscriptionOptsList: OrderbookChannelSubscriptionOpts[] = [];
|
||||
/**
|
||||
* Instantiates a new WebSocketOrderbookChannel instance
|
||||
* @param url The relayer API base WS url you would like to interact with
|
||||
* @param config The configuration object. Look up the type for the description.
|
||||
* @param client A WebSocket client
|
||||
* @param handler An OrderbookChannelHandler instance that responds to various
|
||||
* channel updates
|
||||
* @return An instance of WebSocketOrderbookChannel
|
||||
*/
|
||||
constructor(url: string, config?: WebSocketOrderbookChannelConfig) {
|
||||
assert.isUri('url', url);
|
||||
if (!_.isUndefined(config)) {
|
||||
assert.doesConformToSchema('config', config, clientSchemas.webSocketOrderbookChannelConfigSchema);
|
||||
}
|
||||
this._apiEndpointUrl = url;
|
||||
this._heartbeatIntervalMs =
|
||||
_.isUndefined(config) || _.isUndefined(config.heartbeatIntervalMs)
|
||||
? DEFAULT_HEARTBEAT_INTERVAL_MS
|
||||
: config.heartbeatIntervalMs;
|
||||
this._client = new WebSocket.client();
|
||||
constructor(client: WebSocket.w3cwebsocket, handler: OrderbookChannelHandler) {
|
||||
assert.isOrderbookChannelHandler('handler', handler);
|
||||
// set private members
|
||||
this._client = client;
|
||||
this._handler = handler;
|
||||
// attach client callbacks
|
||||
this._client.onerror = err => {
|
||||
this._handler.onError(this, err);
|
||||
};
|
||||
this._client.onclose = () => {
|
||||
this._handler.onClose(this);
|
||||
};
|
||||
this._client.onmessage = message => {
|
||||
this._handleWebSocketMessage(message);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Subscribe to orderbook snapshots and updates from the websocket
|
||||
* @param subscriptionOpts An OrderbookChannelSubscriptionOpts instance describing which
|
||||
* token pair to subscribe to
|
||||
* @param handler An OrderbookChannelHandler instance that responds to various
|
||||
* channel updates
|
||||
*/
|
||||
public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler): void {
|
||||
assert.doesConformToSchema(
|
||||
'subscriptionOpts',
|
||||
subscriptionOpts,
|
||||
schemas.relayerApiOrderbookChannelSubscribePayload,
|
||||
);
|
||||
assert.isFunction('handler.onSnapshot', _.get(handler, 'onSnapshot'));
|
||||
assert.isFunction('handler.onUpdate', _.get(handler, 'onUpdate'));
|
||||
assert.isFunction('handler.onError', _.get(handler, 'onError'));
|
||||
assert.isFunction('handler.onClose', _.get(handler, 'onClose'));
|
||||
this._subscriptionCounter += 1;
|
||||
public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts): void {
|
||||
assert.isOrderbookChannelSubscriptionOpts('subscriptionOpts', subscriptionOpts);
|
||||
assert.assert(this._client.readyState === WebSocket.w3cwebsocket.OPEN, 'WebSocket connection is closed');
|
||||
this._subscriptionOptsList.push(subscriptionOpts);
|
||||
// TODO: update requestId management to use UUIDs for v2
|
||||
const subscribeMessage = {
|
||||
type: 'subscribe',
|
||||
channel: 'orderbook',
|
||||
requestId: this._subscriptionCounter,
|
||||
requestId: this._subscriptionOptsList.length - 1,
|
||||
payload: subscriptionOpts,
|
||||
};
|
||||
this._getConnection((error, connection) => {
|
||||
if (!_.isUndefined(error)) {
|
||||
handler.onError(this, subscriptionOpts, error);
|
||||
} else if (!_.isUndefined(connection) && connection.connected) {
|
||||
connection.on(WebsocketConnectionEventType.Error, wsError => {
|
||||
handler.onError(this, subscriptionOpts, wsError);
|
||||
});
|
||||
connection.on(WebsocketConnectionEventType.Close, (_code: number, _desc: string) => {
|
||||
handler.onClose(this, subscriptionOpts);
|
||||
});
|
||||
connection.on(WebsocketConnectionEventType.Message, message => {
|
||||
this._handleWebSocketMessage(subscribeMessage.requestId, subscriptionOpts, message, handler);
|
||||
});
|
||||
connection.sendUTF(JSON.stringify(subscribeMessage));
|
||||
}
|
||||
});
|
||||
this._client.send(JSON.stringify(subscribeMessage));
|
||||
}
|
||||
/**
|
||||
* Close the websocket and stop receiving updates
|
||||
*/
|
||||
public close(): void {
|
||||
if (!_.isUndefined(this._connectionIfExists)) {
|
||||
this._connectionIfExists.close();
|
||||
}
|
||||
if (!_.isUndefined(this._heartbeatTimerIfExists)) {
|
||||
clearInterval(this._heartbeatTimerIfExists);
|
||||
}
|
||||
this._client.close();
|
||||
}
|
||||
private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void): void {
|
||||
if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
|
||||
callback(undefined, this._connectionIfExists);
|
||||
} else {
|
||||
this._client.on(WebsocketClientEventType.Connect, connection => {
|
||||
this._connectionIfExists = connection;
|
||||
if (this._heartbeatIntervalMs >= MINIMUM_HEARTBEAT_INTERVAL_MS) {
|
||||
this._heartbeatTimerIfExists = setInterval(() => {
|
||||
connection.ping('');
|
||||
}, this._heartbeatIntervalMs);
|
||||
} else {
|
||||
callback(
|
||||
new Error(
|
||||
`Heartbeat interval is ${
|
||||
this._heartbeatIntervalMs
|
||||
}ms which is less than the required minimum of ${MINIMUM_HEARTBEAT_INTERVAL_MS}ms`,
|
||||
),
|
||||
undefined,
|
||||
private _handleWebSocketMessage(message: any): void {
|
||||
if (_.isUndefined(message.data)) {
|
||||
this._handler.onError(this, new Error(`Message does not contain data. Url: ${this._client.url}`));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const data = message.data;
|
||||
const parserResult = orderbookChannelMessageParser.parse(data);
|
||||
const subscriptionOpts = this._subscriptionOptsList[parserResult.requestId];
|
||||
if (_.isUndefined(subscriptionOpts)) {
|
||||
this._handler.onError(
|
||||
this,
|
||||
new Error(`Message has unknown requestId. Url: ${this._client.url} Message: ${data}`),
|
||||
);
|
||||
return;
|
||||
}
|
||||
switch (parserResult.type) {
|
||||
case OrderbookChannelMessageTypes.Snapshot: {
|
||||
this._handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
|
||||
break;
|
||||
}
|
||||
case OrderbookChannelMessageTypes.Update: {
|
||||
this._handler.onUpdate(this, subscriptionOpts, parserResult.payload);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
this._handler.onError(
|
||||
this,
|
||||
new Error(`Message has unknown type parameter. Url: ${this._client.url} Message: ${data}`),
|
||||
subscriptionOpts,
|
||||
);
|
||||
}
|
||||
callback(undefined, this._connectionIfExists);
|
||||
});
|
||||
this._client.on(WebsocketClientEventType.ConnectFailed, error => {
|
||||
callback(error, undefined);
|
||||
});
|
||||
this._client.connect(this._apiEndpointUrl);
|
||||
}
|
||||
}
|
||||
private _handleWebSocketMessage(
|
||||
requestId: number,
|
||||
subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
||||
message: WebSocket.IMessage,
|
||||
handler: OrderbookChannelHandler,
|
||||
): void {
|
||||
if (!_.isUndefined(message.utf8Data)) {
|
||||
try {
|
||||
const utf8Data = message.utf8Data;
|
||||
const parserResult = orderbookChannelMessageParser.parse(utf8Data);
|
||||
if (parserResult.requestId === requestId) {
|
||||
switch (parserResult.type) {
|
||||
case OrderbookChannelMessageTypes.Snapshot: {
|
||||
handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
|
||||
break;
|
||||
}
|
||||
case OrderbookChannelMessageTypes.Update: {
|
||||
handler.onUpdate(this, subscriptionOpts, parserResult.payload);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
handler.onError(
|
||||
this,
|
||||
subscriptionOpts,
|
||||
new Error(`Message has missing a type parameter: ${utf8Data}`),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
handler.onError(this, subscriptionOpts, error);
|
||||
}
|
||||
} else {
|
||||
handler.onError(this, subscriptionOpts, new Error(`Message does not contain utf8Data`));
|
||||
} catch (error) {
|
||||
this._handler.onError(this, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
45
packages/connect/test/orderbook_channel_factory_test.ts
Normal file
45
packages/connect/test/orderbook_channel_factory_test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import * as chai from 'chai';
|
||||
import * as dirtyChai from 'dirty-chai';
|
||||
import * as _ from 'lodash';
|
||||
import 'mocha';
|
||||
|
||||
import { orderbookChannelFactory } from '../src/orderbook_channel_factory';
|
||||
|
||||
chai.config.includeStack = true;
|
||||
chai.use(dirtyChai);
|
||||
const expect = chai.expect;
|
||||
const emptyOrderbookChannelHandler = {
|
||||
onSnapshot: () => {
|
||||
_.noop();
|
||||
},
|
||||
onUpdate: () => {
|
||||
_.noop();
|
||||
},
|
||||
onError: () => {
|
||||
_.noop();
|
||||
},
|
||||
onClose: () => {
|
||||
_.noop();
|
||||
},
|
||||
};
|
||||
|
||||
describe('orderbookChannelFactory', () => {
|
||||
const websocketUrl = 'ws://localhost:8080';
|
||||
describe('#createWebSocketOrderbookChannelAsync', () => {
|
||||
it('throws when input is not a url', () => {
|
||||
const badUrlInput = 54;
|
||||
expect(
|
||||
orderbookChannelFactory.createWebSocketOrderbookChannelAsync(
|
||||
badUrlInput as any,
|
||||
emptyOrderbookChannelHandler,
|
||||
),
|
||||
).to.be.rejected();
|
||||
});
|
||||
it('throws when handler has the incorrect members', () => {
|
||||
const badHandlerInput = {};
|
||||
expect(
|
||||
orderbookChannelFactory.createWebSocketOrderbookChannelAsync(websocketUrl, badHandlerInput as any),
|
||||
).to.be.rejected();
|
||||
});
|
||||
});
|
||||
});
|
@@ -2,60 +2,58 @@ import * as chai from 'chai';
|
||||
import * as dirtyChai from 'dirty-chai';
|
||||
import * as _ from 'lodash';
|
||||
import 'mocha';
|
||||
import * as Sinon from 'sinon';
|
||||
import * as WebSocket from 'websocket';
|
||||
|
||||
import { WebSocketOrderbookChannel } from '../src/ws_orderbook_channel';
|
||||
|
||||
chai.config.includeStack = true;
|
||||
chai.use(dirtyChai);
|
||||
const expect = chai.expect;
|
||||
const emptyOrderbookChannelHandler = {
|
||||
onSnapshot: () => {
|
||||
_.noop();
|
||||
},
|
||||
onUpdate: () => {
|
||||
_.noop();
|
||||
},
|
||||
onError: () => {
|
||||
_.noop();
|
||||
},
|
||||
onClose: () => {
|
||||
_.noop();
|
||||
},
|
||||
};
|
||||
|
||||
describe('WebSocketOrderbookChannel', () => {
|
||||
const websocketUrl = 'ws://localhost:8080';
|
||||
const orderbookChannel = new WebSocketOrderbookChannel(websocketUrl);
|
||||
const openClient = new WebSocket.w3cwebsocket(websocketUrl);
|
||||
Sinon.stub(openClient, 'readyState').get(() => WebSocket.w3cwebsocket.OPEN);
|
||||
Sinon.stub(openClient, 'send').callsFake(_.noop.bind(_));
|
||||
const openOrderbookChannel = new WebSocketOrderbookChannel(openClient, emptyOrderbookChannelHandler);
|
||||
const subscriptionOpts = {
|
||||
baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
|
||||
quoteTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
|
||||
snapshot: true,
|
||||
limit: 100,
|
||||
};
|
||||
const emptyOrderbookChannelHandler = {
|
||||
onSnapshot: () => {
|
||||
_.noop();
|
||||
},
|
||||
onUpdate: () => {
|
||||
_.noop();
|
||||
},
|
||||
onError: () => {
|
||||
_.noop();
|
||||
},
|
||||
onClose: () => {
|
||||
_.noop();
|
||||
},
|
||||
};
|
||||
describe('#subscribe', () => {
|
||||
it('throws when subscriptionOpts does not conform to schema', () => {
|
||||
const badSubscribeCall = orderbookChannel.subscribe.bind(
|
||||
orderbookChannel,
|
||||
{},
|
||||
emptyOrderbookChannelHandler,
|
||||
);
|
||||
const badSubscribeCall = openOrderbookChannel.subscribe.bind(openOrderbookChannel, {});
|
||||
expect(badSubscribeCall).throws(
|
||||
'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
|
||||
);
|
||||
});
|
||||
it('throws when handler has the incorrect members', () => {
|
||||
const badSubscribeCall = orderbookChannel.subscribe.bind(orderbookChannel, subscriptionOpts, {});
|
||||
expect(badSubscribeCall).throws(
|
||||
'Expected handler.onSnapshot to be of type function, encountered: undefined',
|
||||
);
|
||||
});
|
||||
it('does not throw when inputs are of correct types', () => {
|
||||
const goodSubscribeCall = orderbookChannel.subscribe.bind(
|
||||
orderbookChannel,
|
||||
subscriptionOpts,
|
||||
emptyOrderbookChannelHandler,
|
||||
);
|
||||
const goodSubscribeCall = openOrderbookChannel.subscribe.bind(openOrderbookChannel, subscriptionOpts);
|
||||
expect(goodSubscribeCall).to.not.throw();
|
||||
});
|
||||
it('throws when client is closed', () => {
|
||||
const closedClient = new WebSocket.w3cwebsocket(websocketUrl);
|
||||
Sinon.stub(closedClient, 'readyState').get(() => WebSocket.w3cwebsocket.CLOSED);
|
||||
const closedOrderbookChannel = new WebSocketOrderbookChannel(closedClient, emptyOrderbookChannelHandler);
|
||||
const badSubscribeCall = closedOrderbookChannel.subscribe.bind(closedOrderbookChannel, subscriptionOpts);
|
||||
expect(badSubscribeCall).throws('WebSocket connection is closed');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -9,6 +9,16 @@
|
||||
"note": "Update to v2 of 0x rpotocol",
|
||||
"pr": 822
|
||||
}
|
||||
],
|
||||
"timestamp": 1531149657
|
||||
},
|
||||
{
|
||||
"timestamp": 1531919263,
|
||||
"version": "0.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.1.1 - _July 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.1.0 - _July 9, 2018_
|
||||
|
||||
* Update Blockstream dep. to V5.0 and no longer force unsubscribe on blockstream error (which are not recoverable)
|
||||
|
||||
## v0.0.5 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/contract-wrappers",
|
||||
"version": "0.0.6",
|
||||
"version": "0.1.1",
|
||||
"description": "Smart TS wrappers for 0x smart contracts",
|
||||
"keywords": [
|
||||
"0xproject",
|
||||
@@ -43,13 +43,13 @@
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0xproject/abi-gen": "^0.3.2",
|
||||
"@0xproject/dev-utils": "^0.4.4",
|
||||
"@0xproject/migrations": "^0.0.8",
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/sol-compiler": "^0.5.2",
|
||||
"@0xproject/subproviders": "^0.10.4",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@0xproject/abi-gen": "^1.0.0",
|
||||
"@0xproject/dev-utils": "^1.0.0",
|
||||
"@0xproject/migrations": "^0.0.10",
|
||||
"@0xproject/monorepo-script": "^1.0.0",
|
||||
"@0xproject/sol-compiler": "^1.0.0",
|
||||
"@0xproject/subproviders": "^1.0.0",
|
||||
"@0xproject/tslint-config": "^1.0.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "^8.0.53",
|
||||
@@ -69,21 +69,21 @@
|
||||
"shx": "^0.2.2",
|
||||
"sinon": "^4.0.0",
|
||||
"source-map-support": "^0.5.0",
|
||||
"tslint": "5.8.0",
|
||||
"typescript": "2.7.1",
|
||||
"web3-provider-engine": "14.0.6"
|
||||
"web3-provider-engine": "14.0.6",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/assert": "^0.3.0",
|
||||
"@0xproject/base-contract": "^0.3.4",
|
||||
"@0xproject/order-utils": "^1.0.0",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"@0xproject/web3-wrapper": "^0.7.1",
|
||||
"@0xproject/fill-scenarios": "^1.0.0",
|
||||
"@0xproject/json-schemas": "^1.0.0",
|
||||
"@0xproject/types": "^1.0.0",
|
||||
"ethereum-types": "^0.0.2",
|
||||
"@0xproject/assert": "^1.0.0",
|
||||
"@0xproject/base-contract": "^1.0.0",
|
||||
"@0xproject/order-utils": "^1.0.0-rc.1",
|
||||
"@0xproject/typescript-typings": "^1.0.0",
|
||||
"@0xproject/utils": "^1.0.0",
|
||||
"@0xproject/web3-wrapper": "^1.0.0",
|
||||
"@0xproject/fill-scenarios": "^1.0.0-rc.1",
|
||||
"@0xproject/json-schemas": "^1.0.0-rc.1",
|
||||
"@0xproject/types": "^1.0.0-rc.1",
|
||||
"ethereum-types": "^1.0.0",
|
||||
"ethereumjs-blockstream": "5.0.0",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
"ethers": "3.0.22",
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { ContractArtifact } from '@0xproject/sol-compiler';
|
||||
import { AbiDecoder, intervalUtils } from '@0xproject/utils';
|
||||
import { AbiDecoder, intervalUtils, logUtils } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { BlockParamLiteral, ContractAbi, FilterObject, LogEntry, LogWithDecodedArgs, RawLog } from 'ethereum-types';
|
||||
import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream';
|
||||
@@ -41,6 +41,13 @@ export abstract class ContractWrapper {
|
||||
};
|
||||
private _onLogAddedSubscriptionToken: string | undefined;
|
||||
private _onLogRemovedSubscriptionToken: string | undefined;
|
||||
private static _onBlockAndLogStreamerError(isVerbose: boolean, err: Error): void {
|
||||
// Since Blockstream errors are all recoverable, we simply log them if the verbose
|
||||
// config is passed in.
|
||||
if (isVerbose) {
|
||||
logUtils.warn(err);
|
||||
}
|
||||
}
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, blockPollingIntervalMs?: number) {
|
||||
this._web3Wrapper = web3Wrapper;
|
||||
this._networkId = networkId;
|
||||
@@ -79,10 +86,11 @@ export abstract class ContractWrapper {
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
abi: ContractAbi,
|
||||
callback: EventCallback<ArgsType>,
|
||||
isVerbose: boolean = false,
|
||||
): string {
|
||||
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
|
||||
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
||||
this._startBlockAndLogStream();
|
||||
this._startBlockAndLogStream(isVerbose);
|
||||
}
|
||||
const filterToken = filterUtils.generateUUID();
|
||||
this._filters[filterToken] = filter;
|
||||
@@ -151,21 +159,21 @@ export abstract class ContractWrapper {
|
||||
}
|
||||
});
|
||||
}
|
||||
private _startBlockAndLogStream(): void {
|
||||
private _startBlockAndLogStream(isVerbose: boolean): void {
|
||||
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
||||
throw new Error(ContractWrappersError.SubscriptionAlreadyPresent);
|
||||
}
|
||||
this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
|
||||
this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
|
||||
this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
|
||||
this._onBlockAndLogStreamerError.bind(this),
|
||||
ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose),
|
||||
);
|
||||
const catchAllLogFilter = {};
|
||||
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
|
||||
this._blockAndLogStreamIntervalIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||
this._reconcileBlockAsync.bind(this),
|
||||
this._blockPollingIntervalMs,
|
||||
this._onReconcileBlockError.bind(this),
|
||||
ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose),
|
||||
);
|
||||
let isRemoved = false;
|
||||
this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
|
||||
@@ -176,20 +184,10 @@ export abstract class ContractWrapper {
|
||||
this._onLogStateChanged.bind(this, isRemoved),
|
||||
);
|
||||
}
|
||||
private _onBlockAndLogStreamerError(err: Error): void {
|
||||
// Propogate all Blockstream subscriber errors to all
|
||||
// top-level subscriptions
|
||||
const filterCallbacks = _.values(this._filterCallbacks);
|
||||
_.each(filterCallbacks, filterCallback => {
|
||||
filterCallback(err);
|
||||
});
|
||||
}
|
||||
private _onReconcileBlockError(err: Error): void {
|
||||
const filterTokens = _.keys(this._filterCallbacks);
|
||||
_.each(filterTokens, filterToken => {
|
||||
this._unsubscribe(filterToken, err);
|
||||
});
|
||||
}
|
||||
// HACK: This should be a package-scoped method (which doesn't exist in TS)
|
||||
// We don't want this method available in the public interface for all classes
|
||||
// who inherit from ContractWrapper, and it is only used by the internal implementation
|
||||
// of those higher classes.
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
private _setNetworkId(networkId: number): void {
|
||||
this._networkId = networkId;
|
||||
|
@@ -347,6 +347,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
|
||||
* @param indexFilterValues An object where the keys are indexed args returned by the event and
|
||||
* the value is the value you are interested in. E.g `{maker: aUserAddressHex}`
|
||||
* @param callback Callback that gets called when a log is added/removed
|
||||
* @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered)
|
||||
* @return Subscription token used later to unsubscribe
|
||||
*/
|
||||
public subscribe<ArgsType extends ERC20TokenEventArgs>(
|
||||
@@ -354,6 +355,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
|
||||
eventName: ERC20TokenEvents,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
callback: EventCallback<ArgsType>,
|
||||
isVerbose: boolean = false,
|
||||
): string {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents);
|
||||
@@ -366,6 +368,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
|
||||
indexFilterValues,
|
||||
artifacts.ERC20Token.compilerOutput.abi,
|
||||
callback,
|
||||
isVerbose,
|
||||
);
|
||||
return subscriptionToken;
|
||||
}
|
||||
|
@@ -342,15 +342,17 @@ export class ERC721TokenWrapper extends ContractWrapper {
|
||||
const normalizedSenderAddress = senderAddress.toLowerCase();
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
const ownerAddress = await this.getOwnerOfAsync(tokenAddress, tokenId);
|
||||
const isApprovedForAll = await this.isApprovedForAllAsync(
|
||||
normalizedTokenAddress,
|
||||
ownerAddress,
|
||||
normalizedSenderAddress,
|
||||
);
|
||||
if (!isApprovedForAll) {
|
||||
const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId);
|
||||
if (approvedAddress !== senderAddress) {
|
||||
throw new Error(ContractWrappersError.ERC721NoApproval);
|
||||
if (normalizedSenderAddress !== ownerAddress) {
|
||||
const isApprovedForAll = await this.isApprovedForAllAsync(
|
||||
normalizedTokenAddress,
|
||||
ownerAddress,
|
||||
normalizedSenderAddress,
|
||||
);
|
||||
if (!isApprovedForAll) {
|
||||
const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId);
|
||||
if (approvedAddress !== normalizedSenderAddress) {
|
||||
throw new Error(ContractWrappersError.ERC721NoApproval);
|
||||
}
|
||||
}
|
||||
}
|
||||
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
||||
@@ -372,6 +374,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
|
||||
* @param indexFilterValues An object where the keys are indexed args returned by the event and
|
||||
* the value is the value you are interested in. E.g `{maker: aUserAddressHex}`
|
||||
* @param callback Callback that gets called when a log is added/removed
|
||||
* @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered)
|
||||
* @return Subscription token used later to unsubscribe
|
||||
*/
|
||||
public subscribe<ArgsType extends ERC721TokenEventArgs>(
|
||||
@@ -379,6 +382,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
|
||||
eventName: ERC721TokenEvents,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
callback: EventCallback<ArgsType>,
|
||||
isVerbose: boolean = false,
|
||||
): string {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents);
|
||||
@@ -391,6 +395,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
|
||||
indexFilterValues,
|
||||
artifacts.ERC721Token.compilerOutput.abi,
|
||||
callback,
|
||||
isVerbose,
|
||||
);
|
||||
return subscriptionToken;
|
||||
}
|
||||
|
@@ -146,6 +146,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
* @param indexFilterValues An object where the keys are indexed args returned by the event and
|
||||
* the value is the value you are interested in. E.g `{_owner: aUserAddressHex}`
|
||||
* @param callback Callback that gets called when a log is added/removed
|
||||
* @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered)
|
||||
* @return Subscription token used later to unsubscribe
|
||||
*/
|
||||
public subscribe<ArgsType extends WETH9EventArgs>(
|
||||
@@ -153,6 +154,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
eventName: WETH9Events,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
callback: EventCallback<ArgsType>,
|
||||
isVerbose: boolean = false,
|
||||
): string {
|
||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||
@@ -165,6 +167,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
indexFilterValues,
|
||||
artifacts.EtherToken.compilerOutput.abi,
|
||||
callback,
|
||||
isVerbose,
|
||||
);
|
||||
return subscriptionToken;
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { schemas } from '@0xproject/json-schemas';
|
||||
import { assetDataUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId, Order, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
@@ -988,12 +989,14 @@ export class ExchangeWrapper extends ContractWrapper {
|
||||
* @param indexFilterValues An object where the keys are indexed args returned by the event and
|
||||
* the value is the value you are interested in. E.g `{maker: aUserAddressHex}`
|
||||
* @param callback Callback that gets called when a log is added/removed
|
||||
* @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered)
|
||||
* @return Subscription token used later to unsubscribe
|
||||
*/
|
||||
public subscribe<ArgsType extends ExchangeEventArgs>(
|
||||
eventName: ExchangeEvents,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
callback: EventCallback<ArgsType>,
|
||||
isVerbose: boolean = false,
|
||||
): string {
|
||||
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||
@@ -1005,6 +1008,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
||||
indexFilterValues,
|
||||
artifacts.Exchange.compilerOutput.abi,
|
||||
callback,
|
||||
isVerbose,
|
||||
);
|
||||
return subscriptionToken;
|
||||
}
|
||||
@@ -1068,9 +1072,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
||||
* Returns the ZRX asset data used by the exchange contract.
|
||||
* @return ZRX asset data
|
||||
*/
|
||||
public async getZRXAssetDataAsync(): Promise<string> {
|
||||
const exchangeInstance = await this._getExchangeContractAsync();
|
||||
const zrxAssetData = exchangeInstance.ZRX_ASSET_DATA.callAsync();
|
||||
public getZRXAssetData(): string {
|
||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||
const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxTokenAddress);
|
||||
return zrxAssetData;
|
||||
}
|
||||
// tslint:disable:no-unused-variable
|
||||
|
@@ -1,7 +1,10 @@
|
||||
export { ContractWrappers } from './contract_wrappers';
|
||||
export { ERC20TokenWrapper } from './contract_wrappers/erc20_token_wrapper';
|
||||
export { ERC721TokenWrapper } from './contract_wrappers/erc721_token_wrapper';
|
||||
export { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper';
|
||||
export { ExchangeWrapper } from './contract_wrappers/exchange_wrapper';
|
||||
export { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper';
|
||||
export { ERC721ProxyWrapper } from './contract_wrappers/erc721_proxy_wrapper';
|
||||
|
||||
export {
|
||||
ContractWrappersError,
|
||||
@@ -23,7 +26,15 @@ export {
|
||||
OrderInfo,
|
||||
} from './types';
|
||||
|
||||
export { Order, SignedOrder, ECSignature, OrderStateValid, OrderStateInvalid, OrderState } from '@0xproject/types';
|
||||
export {
|
||||
Order,
|
||||
SignedOrder,
|
||||
ECSignature,
|
||||
OrderStateValid,
|
||||
OrderStateInvalid,
|
||||
OrderState,
|
||||
AssetProxyId,
|
||||
} from '@0xproject/types';
|
||||
|
||||
export {
|
||||
BlockParamLiteral,
|
||||
@@ -57,6 +68,7 @@ export {
|
||||
ERC721TokenApprovalForAllEventArgs,
|
||||
ERC721TokenTransferEventArgs,
|
||||
ERC721TokenEvents,
|
||||
ERC721TokenEventArgs,
|
||||
} from './contract_wrappers/generated/erc721_token';
|
||||
|
||||
export {
|
||||
|
@@ -8,8 +8,8 @@ export const contractWrappersPrivateNetworkConfigSchema = {
|
||||
gasPrice: { $ref: '/Number' },
|
||||
zrxContractAddress: { $ref: '/Address' },
|
||||
exchangeContractAddress: { $ref: '/Address' },
|
||||
tokenRegistryContractAddress: { $ref: '/Address' },
|
||||
tokenTransferProxyContractAddress: { $ref: '/Address' },
|
||||
erc20ProxyContractAddress: { $ref: '/Address' },
|
||||
erc721ProxyContractAddress: { $ref: '/Address' },
|
||||
blockPollingIntervalMs: { type: 'number' },
|
||||
orderWatcherConfig: {
|
||||
type: 'object',
|
||||
@@ -30,7 +30,7 @@ export const contractWrappersPrivateNetworkConfigSchema = {
|
||||
'networkId',
|
||||
'zrxContractAddress',
|
||||
'exchangeContractAddress',
|
||||
'tokenRegistryContractAddress',
|
||||
'tokenTransferProxyContractAddress',
|
||||
'erc20ProxyContractAddress',
|
||||
'erc721ProxyContractAddress',
|
||||
],
|
||||
};
|
||||
|
@@ -22,8 +22,8 @@ export const contractWrappersPublicNetworkConfigSchema = {
|
||||
gasPrice: { $ref: '/Number' },
|
||||
zrxContractAddress: { $ref: '/Address' },
|
||||
exchangeContractAddress: { $ref: '/Address' },
|
||||
tokenRegistryContractAddress: { $ref: '/Address' },
|
||||
tokenTransferProxyContractAddress: { $ref: '/Address' },
|
||||
erc20ProxyContractAddress: { $ref: '/Address' },
|
||||
erc721ProxyContractAddress: { $ref: '/Address' },
|
||||
blockPollingIntervalMs: { type: 'number' },
|
||||
orderWatcherConfig: {
|
||||
type: 'object',
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { assert as sharedAssert } from '@0xproject/assert';
|
||||
// We need those two unused imports because they're actually used by sharedAssert which gets injected here
|
||||
// HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here
|
||||
import { Schema } from '@0xproject/json-schemas'; // tslint:disable-line:no-unused-variable
|
||||
import { isValidSignatureAsync } from '@0xproject/order-utils';
|
||||
import { ECSignature } from '@0xproject/types'; // tslint:disable-line:no-unused-variable
|
||||
|
@@ -1,11 +1,10 @@
|
||||
import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
|
||||
import { EmptyWalletSubprovider } from '@0xproject/subproviders';
|
||||
import { EmptyWalletSubprovider, Web3ProviderEngine } from '@0xproject/subproviders';
|
||||
import { DoneCallback } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import 'mocha';
|
||||
import Web3ProviderEngine = require('web3-provider-engine');
|
||||
|
||||
import {
|
||||
BlockParamLiteral,
|
||||
|
@@ -1,11 +1,10 @@
|
||||
import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
|
||||
import { EmptyWalletSubprovider } from '@0xproject/subproviders';
|
||||
import { EmptyWalletSubprovider, Web3ProviderEngine } from '@0xproject/subproviders';
|
||||
import { DoneCallback } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import 'mocha';
|
||||
import Web3ProviderEngine = require('web3-provider-engine');
|
||||
|
||||
import {
|
||||
BlockParamLiteral,
|
||||
|
@@ -336,15 +336,19 @@ describe('EtherTokenWrapper', () => {
|
||||
describe('#getLogsAsync', () => {
|
||||
let etherTokenAddress: string;
|
||||
let erc20ProxyAddress: string;
|
||||
const blockRange: BlockRange = {
|
||||
fromBlock: 0,
|
||||
toBlock: BlockParamLiteral.Latest,
|
||||
};
|
||||
let blockRange: BlockRange;
|
||||
let txHash: string;
|
||||
before(() => {
|
||||
before(async () => {
|
||||
addressWithETH = userAddresses[0];
|
||||
etherTokenAddress = tokenUtils.getWethTokenAddress();
|
||||
erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
|
||||
// Start the block range after all migrations to avoid unexpected logs
|
||||
const currentBlock = await web3Wrapper.getBlockNumberAsync();
|
||||
const fromBlock = currentBlock + 1;
|
||||
blockRange = {
|
||||
fromBlock,
|
||||
toBlock: BlockParamLiteral.Latest,
|
||||
};
|
||||
});
|
||||
it('should get logs with decoded args emitted by Approval', async () => {
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
|
||||
import { FillScenarios } from '@0xproject/fill-scenarios';
|
||||
import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { assetDataUtils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { DoneCallback, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
@@ -53,7 +53,6 @@ describe('ExchangeWrapper', () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
contractWrappers = new ContractWrappers(provider, config);
|
||||
exchangeContractAddress = contractWrappers.exchange.getContractAddress();
|
||||
const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
|
||||
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
|
||||
zrxTokenAddress = tokenUtils.getProtocolTokenAddress();
|
||||
fillScenarios = new FillScenarios(
|
||||
@@ -61,13 +60,14 @@ describe('ExchangeWrapper', () => {
|
||||
userAddresses,
|
||||
zrxTokenAddress,
|
||||
exchangeContractAddress,
|
||||
erc20ProxyAddress,
|
||||
contractWrappers.erc20Proxy.getContractAddress(),
|
||||
contractWrappers.erc721Proxy.getContractAddress(),
|
||||
);
|
||||
[coinbase, makerAddress, takerAddress, feeRecipient, anotherMakerAddress] = userAddresses;
|
||||
[makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
|
||||
[makerAssetData, takerAssetData] = [
|
||||
assetProxyUtils.encodeERC20AssetData(makerTokenAddress),
|
||||
assetProxyUtils.encodeERC20AssetData(takerTokenAddress),
|
||||
assetDataUtils.encodeERC20AssetData(makerTokenAddress),
|
||||
assetDataUtils.encodeERC20AssetData(takerTokenAddress),
|
||||
];
|
||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerAssetData,
|
||||
@@ -264,8 +264,8 @@ describe('ExchangeWrapper', () => {
|
||||
});
|
||||
});
|
||||
describe('#getZRXAssetData', () => {
|
||||
it('should get the asset data', async () => {
|
||||
const ZRX_ASSET_DATA = await contractWrappers.exchange.getZRXAssetDataAsync();
|
||||
it('should get the asset data', () => {
|
||||
const ZRX_ASSET_DATA = contractWrappers.exchange.getZRXAssetData();
|
||||
const ASSET_DATA_HEX_LENGTH = 74;
|
||||
expect(ZRX_ASSET_DATA).to.have.length(ASSET_DATA_HEX_LENGTH);
|
||||
});
|
||||
|
@@ -7,7 +7,7 @@ before('migrate contracts', async function(): Promise<void> {
|
||||
// HACK: Since the migrations take longer then our global mocha timeout limit
|
||||
// we manually increase it for this before hook.
|
||||
const mochaTestTimeoutMs = 50000;
|
||||
this.timeout(mochaTestTimeoutMs);
|
||||
this.timeout(mochaTestTimeoutMs); // tslint:disable-line:no-invalid-this
|
||||
const txDefaults = {
|
||||
gas: devConstants.GAS_LIMIT,
|
||||
from: devConstants.TESTRPC_FIRST_ADDRESS,
|
||||
|
@@ -49,44 +49,6 @@ describe('SubscriptionTest', () => {
|
||||
_.each(stubs, s => s.restore());
|
||||
stubs = [];
|
||||
});
|
||||
it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const errMsg = 'Error fetching block';
|
||||
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
|
||||
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC20TokenEvents.Approval,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
coinbase,
|
||||
addressWithoutFunds,
|
||||
allowanceAmount,
|
||||
);
|
||||
})().catch(done);
|
||||
});
|
||||
it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const errMsg = 'Error fetching logs';
|
||||
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
|
||||
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC20TokenEvents.Approval,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
coinbase,
|
||||
addressWithoutFunds,
|
||||
allowanceAmount,
|
||||
);
|
||||
})().catch(done);
|
||||
});
|
||||
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = (err: Error | null, _logEvent?: DecodedLogEvent<ERC20TokenApprovalEventArgs>) =>
|
||||
|
@@ -25,6 +25,7 @@
|
||||
"DummyERC721Token",
|
||||
"ERC20Proxy",
|
||||
"ERC20Token",
|
||||
"ERC721Token",
|
||||
"ERC721Proxy",
|
||||
"Exchange",
|
||||
"ExchangeWrapper",
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "contracts",
|
||||
"version": "2.1.33",
|
||||
"version": "2.1.35",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -46,11 +46,11 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md",
|
||||
"devDependencies": {
|
||||
"@0xproject/abi-gen": "^0.3.2",
|
||||
"@0xproject/dev-utils": "^0.4.4",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@0xproject/subproviders": "^0.10.1",
|
||||
"@0xproject/sol-cov": "^0.1.1",
|
||||
"@0xproject/abi-gen": "^1.0.0",
|
||||
"@0xproject/dev-utils": "^1.0.0",
|
||||
"@0xproject/tslint-config": "^1.0.0",
|
||||
"@0xproject/subproviders": "^1.0.0",
|
||||
"@0xproject/sol-cov": "^0.1.3",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/bn.js": "^4.11.0",
|
||||
"@types/node": "^8.0.53",
|
||||
@@ -67,19 +67,19 @@
|
||||
"shx": "^0.2.2",
|
||||
"solc": "^0.4.24",
|
||||
"solhint": "^1.2.1",
|
||||
"tslint": "5.8.0",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "2.7.1",
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/base-contract": "^0.3.4",
|
||||
"@0xproject/order-utils": "^1.0.0",
|
||||
"@0xproject/sol-compiler": "^0.5.2",
|
||||
"@0xproject/types": "^1.0.0",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"@0xproject/web3-wrapper": "^0.7.1",
|
||||
"ethereum-types": "^0.0.2",
|
||||
"@0xproject/base-contract": "^1.0.0",
|
||||
"@0xproject/order-utils": "^1.0.0-rc.1",
|
||||
"@0xproject/sol-compiler": "^1.0.0",
|
||||
"@0xproject/types": "^1.0.0-rc.1",
|
||||
"@0xproject/typescript-typings": "^1.0.0",
|
||||
"@0xproject/utils": "^1.0.0",
|
||||
"@0xproject/web3-wrapper": "^1.0.0",
|
||||
"ethereum-types": "^1.0.0",
|
||||
"bn.js": "^4.11.8",
|
||||
"ethereumjs-abi": "^0.6.4",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
pragma solidity ^0.4.10;
|
||||
|
||||
import "../../current/multisig/MultiSigWalletWithTimeLock.sol";
|
||||
import "../../2.0.0/multisig/MultiSigWalletWithTimeLock.sol";
|
||||
|
||||
contract MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress is MultiSigWalletWithTimeLock {
|
||||
|
||||
@@ -79,4 +79,4 @@ contract MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress is MultiSigWall
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -40,7 +40,6 @@ contract Forwarder is
|
||||
address _exchange,
|
||||
address _etherToken,
|
||||
address _zrxToken,
|
||||
bytes4 _erc20AssetProxyId,
|
||||
bytes memory _zrxAssetData,
|
||||
bytes memory _wethAssetData
|
||||
)
|
||||
|
@@ -16,16 +16,14 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.10;
|
||||
pragma solidity 0.4.10;
|
||||
|
||||
import "../../multisig/MultiSigWalletWithTimeLock.sol";
|
||||
import "../../utils/LibBytes/LibBytes.sol";
|
||||
|
||||
|
||||
contract AssetProxyOwner is
|
||||
MultiSigWalletWithTimeLock
|
||||
{
|
||||
using LibBytes for bytes;
|
||||
|
||||
event AssetProxyRegistration(address assetProxyContract, bool isRegistered);
|
||||
|
||||
@@ -40,7 +38,7 @@ contract AssetProxyOwner is
|
||||
modifier validRemoveAuthorizedAddressAtIndexTx(uint256 transactionId) {
|
||||
Transaction storage tx = transactions[transactionId];
|
||||
require(isAssetProxyRegistered[tx.destination]);
|
||||
require(tx.data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR);
|
||||
require(readBytes4(tx.data, 0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR);
|
||||
_;
|
||||
}
|
||||
|
||||
@@ -97,4 +95,25 @@ contract AssetProxyOwner is
|
||||
tx.executed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Reads an unpadded bytes4 value from a position in a byte array.
|
||||
/// @param b Byte array containing a bytes4 value.
|
||||
/// @param index Index in byte array of bytes4 value.
|
||||
/// @return bytes4 value from byte array.
|
||||
function readBytes4(
|
||||
bytes memory b,
|
||||
uint256 index
|
||||
)
|
||||
internal
|
||||
returns (bytes4 result)
|
||||
{
|
||||
require(b.length >= index + 4);
|
||||
assembly {
|
||||
result := mload(add(b, 32))
|
||||
// Solidity does not require us to clean the trailing bytes.
|
||||
// We do it anyway
|
||||
result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -154,6 +154,9 @@ contract MixinExchangeCore is
|
||||
// Compute the order hash
|
||||
orderInfo.orderHash = getOrderHash(order);
|
||||
|
||||
// Fetch filled amount
|
||||
orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash];
|
||||
|
||||
// If order.makerAssetAmount is zero, we also reject the order.
|
||||
// While the Exchange contract handles them correctly, they create
|
||||
// edge cases in the supporting infrastructure because they have
|
||||
@@ -172,6 +175,12 @@ contract MixinExchangeCore is
|
||||
return orderInfo;
|
||||
}
|
||||
|
||||
// Validate order availability
|
||||
if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) {
|
||||
orderInfo.orderStatus = uint8(OrderStatus.FULLY_FILLED);
|
||||
return orderInfo;
|
||||
}
|
||||
|
||||
// Validate order expiration
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
if (block.timestamp >= order.expirationTimeSeconds) {
|
||||
@@ -189,13 +198,6 @@ contract MixinExchangeCore is
|
||||
return orderInfo;
|
||||
}
|
||||
|
||||
// Fetch filled amount and validate order availability
|
||||
orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash];
|
||||
if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) {
|
||||
orderInfo.orderStatus = uint8(OrderStatus.FULLY_FILLED);
|
||||
return orderInfo;
|
||||
}
|
||||
|
||||
// All other statuses are ruled out: order is Fillable
|
||||
orderInfo.orderStatus = uint8(OrderStatus.FILLABLE);
|
||||
return orderInfo;
|
||||
|
@@ -529,4 +529,20 @@ contract MixinWrapperFunctions is
|
||||
cancelOrder(orders[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Fetches information for all passed in orders.
|
||||
/// @param orders Array of order specifications.
|
||||
/// @return Array of OrderInfo instances that correspond to each order.
|
||||
function getOrdersInfo(LibOrder.Order[] memory orders)
|
||||
public
|
||||
view
|
||||
returns (LibOrder.OrderInfo[] memory)
|
||||
{
|
||||
uint256 length = orders.length;
|
||||
LibOrder.OrderInfo[] memory ordersInfo = new LibOrder.OrderInfo[](length);
|
||||
for (uint256 i = 0; i < length; i++) {
|
||||
ordersInfo[i] = getOrderInfo(orders[i]);
|
||||
}
|
||||
return ordersInfo;
|
||||
}
|
||||
}
|
||||
|
@@ -149,4 +149,12 @@ contract IWrapperFunctions {
|
||||
/// @param orders Array of order specifications.
|
||||
function batchCancelOrders(LibOrder.Order[] memory orders)
|
||||
public;
|
||||
|
||||
/// @dev Fetches information for all passed in orders
|
||||
/// @param orders Array of order specifications.
|
||||
/// @return Array of OrderInfo instances that correspond to each order.
|
||||
function getOrdersInfo(LibOrder.Order[] memory orders)
|
||||
public
|
||||
view
|
||||
returns (LibOrder.OrderInfo[] memory);
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity 0.4.10;
|
||||
|
||||
import "../../protocol/AssetProxyOwner/AssetProxyOwner.sol";
|
||||
|
||||
@@ -26,7 +26,7 @@ contract TestAssetProxyOwner is
|
||||
AssetProxyOwner
|
||||
{
|
||||
|
||||
constructor(
|
||||
function TestAssetProxyOwner(
|
||||
address[] memory _owners,
|
||||
address[] memory _assetProxyContracts,
|
||||
uint256 _required,
|
||||
@@ -38,7 +38,6 @@ contract TestAssetProxyOwner is
|
||||
|
||||
function testValidRemoveAuthorizedAddressAtIndexTx(uint256 id)
|
||||
public
|
||||
view
|
||||
validRemoveAuthorizedAddressAtIndexTx(id)
|
||||
returns (bool)
|
||||
{
|
||||
@@ -51,9 +50,23 @@ contract TestAssetProxyOwner is
|
||||
/// @return Successful if data is a call to `removeAuthorizedAddressAtIndex`.
|
||||
function isFunctionRemoveAuthorizedAddressAtIndex(bytes memory data)
|
||||
public
|
||||
pure
|
||||
returns (bool)
|
||||
{
|
||||
return data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR;
|
||||
return readBytes4(data, 0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR;
|
||||
}
|
||||
|
||||
/// @dev Reads an unpadded bytes4 value from a position in a byte array.
|
||||
/// @param b Byte array containing a bytes4 value.
|
||||
/// @param index Index in byte array of bytes4 value.
|
||||
/// @return bytes4 value from byte array.
|
||||
function publicReadBytes4(
|
||||
bytes memory b,
|
||||
uint256 index
|
||||
)
|
||||
public
|
||||
returns (bytes4 result)
|
||||
{
|
||||
result = readBytes4(b, index);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -457,7 +457,8 @@ library LibBytes {
|
||||
/// @return bytes4 value from byte array.
|
||||
function readBytes4(
|
||||
bytes memory b,
|
||||
uint256 index)
|
||||
uint256 index
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (bytes4 result)
|
||||
|
@@ -7,8 +7,14 @@ contract SafeMath {
|
||||
pure
|
||||
returns (uint256)
|
||||
{
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint256 c = a * b;
|
||||
assert(a == 0 || c / a == b);
|
||||
require(
|
||||
c / a == b,
|
||||
"UINT256_OVERFLOW"
|
||||
);
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -26,7 +32,10 @@ contract SafeMath {
|
||||
pure
|
||||
returns (uint256)
|
||||
{
|
||||
assert(b <= a);
|
||||
require(
|
||||
b <= a,
|
||||
"UINT256_OVERFLOW"
|
||||
);
|
||||
return a - b;
|
||||
}
|
||||
|
||||
@@ -36,7 +45,10 @@ contract SafeMath {
|
||||
returns (uint256)
|
||||
{
|
||||
uint256 c = a + b;
|
||||
assert(c >= a);
|
||||
require(
|
||||
c >= a,
|
||||
"UINT256_OVERFLOW"
|
||||
);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { assetDataUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { RevertReason } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
@@ -23,6 +23,7 @@ import { constants } from '../utils/constants';
|
||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../utils/erc721_wrapper';
|
||||
import { LogDecoder } from '../utils/log_decoder';
|
||||
import { typeEncodingUtils } from '../utils/type_encoding_utils';
|
||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -107,7 +108,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
describe('transferFrom', () => {
|
||||
it('should successfully transfer tokens', async () => {
|
||||
// Construct ERC20 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
||||
const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
const amount = new BigNumber(10);
|
||||
@@ -137,7 +138,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should do nothing if transferring 0 amount of a token', async () => {
|
||||
// Construct ERC20 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
||||
const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
const amount = new BigNumber(0);
|
||||
@@ -167,7 +168,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should throw if allowances are too low', async () => {
|
||||
// Construct ERC20 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
||||
const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
|
||||
// Create allowance less than transfer amount. Set allowance on proxy.
|
||||
const allowance = new BigNumber(0);
|
||||
const amount = new BigNumber(10);
|
||||
@@ -196,7 +197,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should throw if requesting address is not authorized', async () => {
|
||||
// Construct ERC20 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
||||
const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const amount = new BigNumber(10);
|
||||
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
||||
@@ -227,7 +228,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
describe('transferFrom', () => {
|
||||
it('should successfully transfer tokens', async () => {
|
||||
// Construct ERC721 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
// Verify pre-condition
|
||||
const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId);
|
||||
expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress);
|
||||
@@ -254,7 +255,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should call onERC721Received when transferring to a smart contract without receiver data', async () => {
|
||||
// Construct ERC721 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
// Verify pre-condition
|
||||
const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId);
|
||||
expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress);
|
||||
@@ -272,7 +273,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
to: erc721Proxy.address,
|
||||
data,
|
||||
from: exchangeAddress,
|
||||
gas: constants.TRANSFER_FROM_GAS,
|
||||
gas: constants.MAX_TRANSFER_FROM_GAS,
|
||||
}),
|
||||
);
|
||||
// Verify that no log was emitted by erc721 receiver
|
||||
@@ -288,8 +289,8 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should call onERC721Received when transferring to a smart contract with receiver data', async () => {
|
||||
// Construct ERC721 asset data
|
||||
const receiverData = ethUtil.bufferToHex(assetProxyUtils.encodeUint256(generatePseudoRandomSalt()));
|
||||
const encodedAssetData = assetProxyUtils.encodeERC721AssetData(
|
||||
const receiverData = ethUtil.bufferToHex(typeEncodingUtils.encodeUint256(generatePseudoRandomSalt()));
|
||||
const encodedAssetData = assetDataUtils.encodeERC721AssetData(
|
||||
erc721Token.address,
|
||||
erc721MakerTokenId,
|
||||
receiverData,
|
||||
@@ -311,7 +312,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
to: erc721Proxy.address,
|
||||
data,
|
||||
from: exchangeAddress,
|
||||
gas: constants.TRANSFER_FROM_GAS,
|
||||
gas: constants.MAX_TRANSFER_FROM_GAS,
|
||||
}),
|
||||
);
|
||||
// Validate log emitted by erc721 receiver
|
||||
@@ -327,8 +328,8 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should throw if there is receiver data but contract does not have onERC721Received', async () => {
|
||||
// Construct ERC721 asset data
|
||||
const receiverData = ethUtil.bufferToHex(assetProxyUtils.encodeUint256(generatePseudoRandomSalt()));
|
||||
const encodedAssetData = assetProxyUtils.encodeERC721AssetData(
|
||||
const receiverData = ethUtil.bufferToHex(typeEncodingUtils.encodeUint256(generatePseudoRandomSalt()));
|
||||
const encodedAssetData = assetDataUtils.encodeERC721AssetData(
|
||||
erc721Token.address,
|
||||
erc721MakerTokenId,
|
||||
receiverData,
|
||||
@@ -349,7 +350,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
to: erc721Proxy.address,
|
||||
data,
|
||||
from: exchangeAddress,
|
||||
gas: constants.TRANSFER_FROM_GAS,
|
||||
gas: constants.MAX_TRANSFER_FROM_GAS,
|
||||
}),
|
||||
RevertReason.TransferFailed,
|
||||
);
|
||||
@@ -357,7 +358,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should throw if transferring 0 amount of a token', async () => {
|
||||
// Construct ERC721 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
// Verify pre-condition
|
||||
const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId);
|
||||
expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress);
|
||||
@@ -381,7 +382,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should throw if transferring > 1 amount of a token', async () => {
|
||||
// Construct ERC721 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
// Verify pre-condition
|
||||
const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId);
|
||||
expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress);
|
||||
@@ -405,7 +406,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should throw if allowances are too low', async () => {
|
||||
// Construct ERC721 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
// Remove transfer approval for makerAddress.
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Token.approve.sendTransactionAsync(constants.NULL_ADDRESS, erc721MakerTokenId, {
|
||||
@@ -433,7 +434,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
|
||||
it('should throw if requesting address is not authorized', async () => {
|
||||
// Construct ERC721 asset data
|
||||
const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const amount = new BigNumber(1);
|
||||
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { assetDataUtils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { RevertReason, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
@@ -15,13 +15,14 @@ import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_pr
|
||||
import { ExchangeCancelEventArgs, ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
||||
import { artifacts } from '../utils/artifacts';
|
||||
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||
import { getLatestBlockTimestampAsync, increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
|
||||
import { chaiSetup } from '../utils/chai_setup';
|
||||
import { constants } from '../utils/constants';
|
||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../utils/order_factory';
|
||||
import { ERC20BalancesByOwner } from '../utils/types';
|
||||
import { ERC20BalancesByOwner, OrderStatus } from '../utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -87,7 +88,7 @@ describe('Exchange core', () => {
|
||||
artifacts.Exchange,
|
||||
provider,
|
||||
txDefaults,
|
||||
assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
);
|
||||
exchangeWrapper = new ExchangeWrapper(exchange, provider);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
|
||||
@@ -114,8 +115,8 @@ describe('Exchange core', () => {
|
||||
exchangeAddress: exchange.address,
|
||||
makerAddress,
|
||||
feeRecipientAddress,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
};
|
||||
const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
|
||||
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
|
||||
@@ -129,11 +130,11 @@ describe('Exchange core', () => {
|
||||
describe('fillOrder', () => {
|
||||
beforeEach(async () => {
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
});
|
||||
|
||||
it('should throw if signature is invalid', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
|
||||
@@ -151,7 +152,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
it('should throw if no value is filled', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
return expectTransactionFailedAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
|
||||
@@ -163,7 +164,7 @@ describe('Exchange core', () => {
|
||||
describe('cancelOrder', () => {
|
||||
beforeEach(async () => {
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
});
|
||||
|
||||
it('should throw if not sent by maker', async () => {
|
||||
@@ -174,7 +175,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
it('should throw if makerAssetAmount is 0', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(0),
|
||||
});
|
||||
|
||||
@@ -185,7 +186,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
it('should throw if takerAssetAmount is 0', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
takerAssetAmount: new BigNumber(0),
|
||||
});
|
||||
|
||||
@@ -229,8 +230,9 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
it('should throw if order is expired', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
expirationTimeSeconds: new BigNumber(currentTimestamp).sub(10),
|
||||
});
|
||||
return expectTransactionFailedAsync(
|
||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||
@@ -239,7 +241,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
it('should throw if rounding error is greater than 0.1%', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1001),
|
||||
takerAssetAmount: new BigNumber(3),
|
||||
});
|
||||
@@ -288,22 +290,22 @@ describe('Exchange core', () => {
|
||||
// Since we cancelled with orderEpoch=1, orders with orderEpoch<=1 will not be processed
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
const signedOrders = [
|
||||
orderFactory.newSignedOrder({
|
||||
await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(9), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(9), 18),
|
||||
salt: new BigNumber(0),
|
||||
}),
|
||||
orderFactory.newSignedOrder({
|
||||
await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(79), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(79), 18),
|
||||
salt: new BigNumber(1),
|
||||
}),
|
||||
orderFactory.newSignedOrder({
|
||||
await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(979), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(979), 18),
|
||||
salt: new BigNumber(2),
|
||||
}),
|
||||
orderFactory.newSignedOrder({
|
||||
await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(7979), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(7979), 18),
|
||||
salt: new BigNumber(3),
|
||||
@@ -350,11 +352,11 @@ describe('Exchange core', () => {
|
||||
// Construct Exchange parameters
|
||||
const makerAssetId = erc721TakerAssetIds[0];
|
||||
const takerAssetId = erc721TakerAssetIds[1];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
});
|
||||
// Verify pre-conditions
|
||||
const initialOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
||||
@@ -373,11 +375,11 @@ describe('Exchange core', () => {
|
||||
// Construct Exchange parameters
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const takerAssetId = erc721MakerAssetIds[1];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
});
|
||||
// Verify pre-conditions
|
||||
const initialOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
||||
@@ -396,11 +398,11 @@ describe('Exchange core', () => {
|
||||
// Construct Exchange parameters
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const takerAssetId = erc721TakerAssetIds[0];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(2),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
});
|
||||
// Verify pre-conditions
|
||||
const initialOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
||||
@@ -419,11 +421,11 @@ describe('Exchange core', () => {
|
||||
// Construct Exchange parameters
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const takerAssetId = erc721TakerAssetIds[0];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: new BigNumber(500),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
});
|
||||
// Verify pre-conditions
|
||||
const initialOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
||||
@@ -441,11 +443,11 @@ describe('Exchange core', () => {
|
||||
it('should throw on partial fill', async () => {
|
||||
// Construct Exchange parameters
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
});
|
||||
// Call Exchange
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
@@ -459,14 +461,12 @@ describe('Exchange core', () => {
|
||||
// Construct Exchange parameters
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const takerAssetId = erc721TakerAssetIds[0];
|
||||
const makerAssetData = assetProxyUtils
|
||||
.encodeERC721AssetData(erc721Token.address, makerAssetId)
|
||||
.slice(0, -2);
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
const makerAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId).slice(0, -2);
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
makerAssetData,
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
});
|
||||
// Verify pre-conditions
|
||||
const initialOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
||||
@@ -481,6 +481,124 @@ describe('Exchange core', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrderInfo', () => {
|
||||
beforeEach(async () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
});
|
||||
it('should return the correct orderInfo for an unfilled valid order', async () => {
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.FILLABLE;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for a fully filled order', async () => {
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
|
||||
const expectedOrderStatus = OrderStatus.FULLY_FILLED;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for a partially filled order', async () => {
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = takerAssetFillAmount;
|
||||
const expectedOrderStatus = OrderStatus.FILLABLE;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for a cancelled and unfilled order', async () => {
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.CANCELLED;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for a cancelled and partially filled order', async () => {
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = takerAssetFillAmount;
|
||||
const expectedOrderStatus = OrderStatus.CANCELLED;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for an expired and unfilled order', async () => {
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
|
||||
await increaseTimeAndMineBlockAsync(timeUntilExpiration);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.EXPIRED;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for an expired and partially filled order', async () => {
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
|
||||
await increaseTimeAndMineBlockAsync(timeUntilExpiration);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = takerAssetFillAmount;
|
||||
const expectedOrderStatus = OrderStatus.EXPIRED;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for an expired and fully filled order', async () => {
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
|
||||
await increaseTimeAndMineBlockAsync(timeUntilExpiration);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
|
||||
// FULLY_FILLED takes precedence over EXPIRED
|
||||
const expectedOrderStatus = OrderStatus.FULLY_FILLED;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for an order with a makerAssetAmount of 0', async () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(0) });
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.INVALID_MAKER_ASSET_AMOUNT;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for an order with a takerAssetAmount of 0', async () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({ takerAssetAmount: new BigNumber(0) });
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.INVALID_TAKER_ASSET_AMOUNT;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
});
|
||||
// tslint:disable:max-file-line-count
|
||||
// tslint:enable:no-unnecessary-type-assertion
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils } from '@0xproject/order-utils';
|
||||
import { assetDataUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId, RevertReason } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
@@ -180,7 +180,7 @@ describe('AssetProxyDispatcher', () => {
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// Construct metadata for ERC20 proxy
|
||||
const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
||||
const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
|
||||
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
@@ -207,7 +207,7 @@ describe('AssetProxyDispatcher', () => {
|
||||
|
||||
it('should throw if dispatching to unregistered proxy', async () => {
|
||||
// Construct metadata for ERC20 proxy
|
||||
const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
||||
const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const amount = new BigNumber(10);
|
||||
return expectTransactionFailedAsync(
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils, EIP712Utils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { assetDataUtils, EIP712Utils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
@@ -38,8 +38,8 @@ describe('Exchange libs', () => {
|
||||
exchangeAddress: libs.address,
|
||||
makerAddress,
|
||||
feeRecipientAddress: addressUtils.generatePseudoRandomAddress(),
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
|
||||
};
|
||||
const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
|
||||
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
|
||||
@@ -71,7 +71,7 @@ describe('Exchange libs', () => {
|
||||
});
|
||||
describe('getOrderHash', () => {
|
||||
it('should output the correct orderHash', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
const orderHashHex = await libs.publicGetOrderHash.callAsync(signedOrder);
|
||||
expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex);
|
||||
});
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils } from '@0xproject/order-utils';
|
||||
import { assetDataUtils } from '@0xproject/order-utils';
|
||||
import { RevertReason } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
@@ -100,7 +100,7 @@ describe('matchOrders', () => {
|
||||
artifacts.Exchange,
|
||||
provider,
|
||||
txDefaults,
|
||||
assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
);
|
||||
exchangeWrapper = new ExchangeWrapper(exchange, provider);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
|
||||
@@ -126,8 +126,8 @@ describe('matchOrders', () => {
|
||||
const defaultOrderParams = {
|
||||
...constants.STATIC_ORDER_PARAMS,
|
||||
exchangeAddress: exchange.address,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
};
|
||||
const privateKeyLeft = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddressLeft)];
|
||||
orderFactoryLeft = new OrderFactory(privateKeyLeft, defaultOrderParams);
|
||||
@@ -150,16 +150,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts when orders completely fill each other', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -182,16 +182,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts when orders completely fill each other and taker doesnt take a profit', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -225,16 +225,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts when left order is completely filled and right order is partially filled', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(20), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(4), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -257,16 +257,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts when right order is completely filled and left order is partially filled', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -289,16 +289,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts when consecutive calls are used to completely fill the left order', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -326,10 +326,10 @@ describe('matchOrders', () => {
|
||||
// Note: This order needs makerAssetAmount=90/takerAssetAmount=[anything <= 45] to fully fill the right order.
|
||||
// However, we use 100/50 to ensure a partial fill as we want to go down the "left fill"
|
||||
// branch in the contract twice for this test.
|
||||
const signedOrderRight2 = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight2 = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -356,17 +356,17 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts when consecutive calls are used to completely fill the right order', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -394,7 +394,7 @@ describe('matchOrders', () => {
|
||||
// Note: This order needs makerAssetAmount=96/takerAssetAmount=48 to fully fill the right order.
|
||||
// However, we use 100/50 to ensure a partial fill as we want to go down the "right fill"
|
||||
// branch in the contract twice for this test.
|
||||
const signedOrderLeft2 = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft2 = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18),
|
||||
@@ -425,16 +425,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts if fee recipient is the same across both matched orders', async () => {
|
||||
const feeRecipientAddress = feeRecipientAddressLeft;
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress,
|
||||
@@ -451,16 +451,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts if taker is also the left order maker', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -478,16 +478,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts if taker is also the right order maker', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -505,16 +505,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts if taker is also the left fee recipient', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -532,16 +532,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts if taker is also the right fee recipient', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -559,16 +559,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should transfer the correct amounts if left maker is the left fee recipient and right maker is the right fee recipient', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: makerAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: makerAddressRight,
|
||||
@@ -585,16 +585,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('Should throw if left order is not fillable', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -610,16 +610,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('Should throw if right order is not fillable', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -635,16 +635,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should throw if there is not a positive spread', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -658,16 +658,16 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should throw if the left maker asset is not equal to the right taker asset ', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -685,18 +685,18 @@ describe('matchOrders', () => {
|
||||
|
||||
it('should throw if the right maker asset is not equal to the left taker asset', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -711,18 +711,18 @@ describe('matchOrders', () => {
|
||||
it('should transfer correct amounts when left order maker asset is an ERC721 token', async () => {
|
||||
// Create orders to match
|
||||
const erc721TokenToTransfer = erc721LeftMakerAssetIds[0];
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
@@ -746,18 +746,18 @@ describe('matchOrders', () => {
|
||||
it('should transfer correct amounts when right order maker asset is an ERC721 token', async () => {
|
||||
// Create orders to match
|
||||
const erc721TokenToTransfer = erc721RightMakerAssetIds[0];
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
|
||||
makerAddress: makerAddressLeft,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
feeRecipientAddress: feeRecipientAddressLeft,
|
||||
});
|
||||
const signedOrderRight = orderFactoryRight.newSignedOrder({
|
||||
const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
|
||||
makerAddress: makerAddressRight,
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { addSignedMessagePrefix, assetProxyUtils, MessagePrefixType, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { addSignedMessagePrefix, assetDataUtils, MessagePrefixType, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { RevertReason, SignatureType, SignedOrder } from '@0xproject/types';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
@@ -78,8 +78,8 @@ describe('MixinSignatureValidator', () => {
|
||||
exchangeAddress: signatureValidator.address,
|
||||
makerAddress,
|
||||
feeRecipientAddress: addressUtils.generatePseudoRandomAddress(),
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
|
||||
};
|
||||
signerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
|
||||
notSignerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(notSignerAddress)];
|
||||
@@ -95,7 +95,7 @@ describe('MixinSignatureValidator', () => {
|
||||
|
||||
describe('isValidSignature', () => {
|
||||
beforeEach(async () => {
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
});
|
||||
|
||||
it('should revert when signature is empty', async () => {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { assetDataUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { OrderWithoutExchangeAddress, RevertReason, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
@@ -88,7 +88,7 @@ describe('Exchange transactions', () => {
|
||||
artifacts.Exchange,
|
||||
provider,
|
||||
txDefaults,
|
||||
assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
);
|
||||
exchangeWrapper = new ExchangeWrapper(exchange, provider);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
|
||||
@@ -107,8 +107,8 @@ describe('Exchange transactions', () => {
|
||||
exchangeAddress: exchange.address,
|
||||
makerAddress,
|
||||
feeRecipientAddress,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultMakerTokenAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultTakerTokenAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerTokenAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerTokenAddress),
|
||||
};
|
||||
makerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
|
||||
takerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)];
|
||||
@@ -121,7 +121,7 @@ describe('Exchange transactions', () => {
|
||||
let takerAssetFillAmount: BigNumber;
|
||||
beforeEach(async () => {
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
|
||||
takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
@@ -226,7 +226,7 @@ describe('Exchange transactions', () => {
|
||||
|
||||
it("should cancel an order if called from the order's sender", async () => {
|
||||
const orderSalt = new BigNumber(0);
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
senderAddress: exchangeWrapperContract.address,
|
||||
salt: orderSalt,
|
||||
});
|
||||
@@ -265,7 +265,7 @@ describe('Exchange transactions', () => {
|
||||
|
||||
it("should not cancel an order if not called from the order's sender", async () => {
|
||||
const orderSalt = new BigNumber(0);
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
senderAddress: exchangeWrapperContract.address,
|
||||
salt: orderSalt,
|
||||
});
|
||||
@@ -349,14 +349,14 @@ describe('Exchange transactions', () => {
|
||||
exchangeAddress: exchange.address,
|
||||
makerAddress,
|
||||
feeRecipientAddress,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultMakerTokenAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultTakerTokenAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerTokenAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerTokenAddress),
|
||||
};
|
||||
whitelistOrderFactory = new OrderFactory(makerPrivateKey, defaultOrderParams);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
signedOrder = whitelistOrderFactory.newSignedOrder();
|
||||
signedOrder = await whitelistOrderFactory.newSignedOrderAsync();
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
});
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils } from '@0xproject/order-utils';
|
||||
import { assetDataUtils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { RevertReason, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
@@ -13,13 +13,14 @@ import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_pr
|
||||
import { ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
||||
import { artifacts } from '../utils/artifacts';
|
||||
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||
import { getLatestBlockTimestampAsync, increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
|
||||
import { chaiSetup } from '../utils/chai_setup';
|
||||
import { constants } from '../utils/constants';
|
||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../utils/order_factory';
|
||||
import { ERC20BalancesByOwner } from '../utils/types';
|
||||
import { ERC20BalancesByOwner, OrderStatus } from '../utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -84,7 +85,7 @@ describe('Exchange wrappers', () => {
|
||||
artifacts.Exchange,
|
||||
provider,
|
||||
txDefaults,
|
||||
assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
);
|
||||
exchangeWrapper = new ExchangeWrapper(exchange, provider);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
|
||||
@@ -111,8 +112,8 @@ describe('Exchange wrappers', () => {
|
||||
exchangeAddress: exchange.address,
|
||||
makerAddress,
|
||||
feeRecipientAddress,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
};
|
||||
const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
|
||||
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
|
||||
@@ -126,7 +127,7 @@ describe('Exchange wrappers', () => {
|
||||
});
|
||||
describe('fillOrKillOrder', () => {
|
||||
it('should transfer the correct amounts', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18),
|
||||
});
|
||||
@@ -170,8 +171,9 @@ describe('Exchange wrappers', () => {
|
||||
});
|
||||
|
||||
it('should throw if a signedOrder is expired', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
expirationTimeSeconds: new BigNumber(currentTimestamp).sub(10),
|
||||
});
|
||||
|
||||
return expectTransactionFailedAsync(
|
||||
@@ -181,7 +183,7 @@ describe('Exchange wrappers', () => {
|
||||
});
|
||||
|
||||
it('should throw if entire takerAssetFillAmount not filled', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder();
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
||||
@@ -196,7 +198,7 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
describe('fillOrderNoThrow', () => {
|
||||
it('should transfer the correct amounts', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18),
|
||||
});
|
||||
@@ -245,7 +247,7 @@ describe('Exchange wrappers', () => {
|
||||
});
|
||||
|
||||
it('should not change erc20Balances if maker erc20Balances are too low to fill order', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18),
|
||||
});
|
||||
|
||||
@@ -255,7 +257,7 @@ describe('Exchange wrappers', () => {
|
||||
});
|
||||
|
||||
it('should not change erc20Balances if taker erc20Balances are too low to fill order', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18),
|
||||
});
|
||||
|
||||
@@ -265,7 +267,7 @@ describe('Exchange wrappers', () => {
|
||||
});
|
||||
|
||||
it('should not change erc20Balances if maker allowances are too low to fill order', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder();
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), {
|
||||
from: makerAddress,
|
||||
@@ -285,7 +287,7 @@ describe('Exchange wrappers', () => {
|
||||
});
|
||||
|
||||
it('should not change erc20Balances if taker allowances are too low to fill order', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder();
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), {
|
||||
from: takerAddress,
|
||||
@@ -306,10 +308,10 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
it('should not change erc20Balances if makerAssetAddress is ZRX, makerAssetAmount + makerFee > maker balance', async () => {
|
||||
const makerZRXBalance = new BigNumber(erc20Balances[makerAddress][zrxToken.address]);
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: makerZRXBalance,
|
||||
makerFee: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
});
|
||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
@@ -318,10 +320,10 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
it('should not change erc20Balances if makerAssetAddress is ZRX, makerAssetAmount + makerFee > maker allowance', async () => {
|
||||
const makerZRXAllowance = await zrxToken.allowance.callAsync(makerAddress, erc20Proxy.address);
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(makerZRXAllowance),
|
||||
makerFee: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
});
|
||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
@@ -330,10 +332,10 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
it('should not change erc20Balances if takerAssetAddress is ZRX, takerAssetAmount + takerFee > taker balance', async () => {
|
||||
const takerZRXBalance = new BigNumber(erc20Balances[takerAddress][zrxToken.address]);
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
takerAssetAmount: takerZRXBalance,
|
||||
takerFee: new BigNumber(1),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
});
|
||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
@@ -342,10 +344,10 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
it('should not change erc20Balances if takerAssetAddress is ZRX, takerAssetAmount + takerFee > taker allowance', async () => {
|
||||
const takerZRXAllowance = await zrxToken.allowance.callAsync(takerAddress, erc20Proxy.address);
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
takerAssetAmount: new BigNumber(takerZRXAllowance),
|
||||
takerFee: new BigNumber(1),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
});
|
||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
@@ -356,11 +358,11 @@ describe('Exchange wrappers', () => {
|
||||
// Construct Exchange parameters
|
||||
const makerAssetId = erc721MakerAssetId;
|
||||
const takerAssetId = erc721TakerAssetId;
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
});
|
||||
// Verify pre-conditions
|
||||
const initialOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
||||
@@ -388,9 +390,9 @@ describe('Exchange wrappers', () => {
|
||||
let signedOrders: SignedOrder[];
|
||||
beforeEach(async () => {
|
||||
signedOrders = [
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
];
|
||||
});
|
||||
|
||||
@@ -696,11 +698,11 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
it('should throw when a signedOrder does not use the same takerAssetAddress', async () => {
|
||||
signedOrders = [
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder({
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync({
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
}),
|
||||
orderFactory.newSignedOrder(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
];
|
||||
|
||||
return expectTransactionFailedAsync(
|
||||
@@ -796,10 +798,10 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
it('should not fill a signedOrder that does not use the same takerAssetAddress', async () => {
|
||||
signedOrders = [
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder({
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync({
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
}),
|
||||
];
|
||||
const takerAssetFillAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18);
|
||||
@@ -914,11 +916,11 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
it('should throw when a signedOrder does not use the same makerAssetAddress', async () => {
|
||||
signedOrders = [
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder({
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
}),
|
||||
orderFactory.newSignedOrder(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
];
|
||||
|
||||
return expectTransactionFailedAsync(
|
||||
@@ -1012,10 +1014,10 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
it('should not fill a signedOrder that does not use the same makerAssetAddress', async () => {
|
||||
signedOrders = [
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder({
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -1069,5 +1071,189 @@ describe('Exchange wrappers', () => {
|
||||
expect(erc20Balances).to.be.deep.equal(newBalances);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrdersInfo', () => {
|
||||
beforeEach(async () => {
|
||||
signedOrders = [
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
await orderFactory.newSignedOrderAsync(),
|
||||
];
|
||||
});
|
||||
it('should get the correct information for multiple unfilled orders', async () => {
|
||||
const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
|
||||
expect(ordersInfo.length).to.be.equal(3);
|
||||
_.forEach(signedOrders, (signedOrder, index) => {
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.FILLABLE;
|
||||
const orderInfo = ordersInfo[index];
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
it('should get the correct information for multiple partially filled orders', async () => {
|
||||
const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
|
||||
await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
|
||||
const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
|
||||
expect(ordersInfo.length).to.be.equal(3);
|
||||
_.forEach(signedOrders, (signedOrder, index) => {
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
|
||||
const expectedOrderStatus = OrderStatus.FILLABLE;
|
||||
const orderInfo = ordersInfo[index];
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
it('should get the correct information for multiple fully filled orders', async () => {
|
||||
await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress);
|
||||
const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
|
||||
expect(ordersInfo.length).to.be.equal(3);
|
||||
_.forEach(signedOrders, (signedOrder, index) => {
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
|
||||
const expectedOrderStatus = OrderStatus.FULLY_FILLED;
|
||||
const orderInfo = ordersInfo[index];
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
it('should get the correct information for multiple cancelled and unfilled orders', async () => {
|
||||
await exchangeWrapper.batchCancelOrdersAsync(signedOrders, makerAddress);
|
||||
const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
|
||||
expect(ordersInfo.length).to.be.equal(3);
|
||||
_.forEach(signedOrders, (signedOrder, index) => {
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.CANCELLED;
|
||||
const orderInfo = ordersInfo[index];
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
it('should get the correct information for multiple cancelled and partially filled orders', async () => {
|
||||
const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
|
||||
await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
|
||||
await exchangeWrapper.batchCancelOrdersAsync(signedOrders, makerAddress);
|
||||
const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
|
||||
expect(ordersInfo.length).to.be.equal(3);
|
||||
_.forEach(signedOrders, (signedOrder, index) => {
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
|
||||
const expectedOrderStatus = OrderStatus.CANCELLED;
|
||||
const orderInfo = ordersInfo[index];
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
it('should get the correct information for multiple expired and unfilled orders', async () => {
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const timeUntilExpiration = signedOrders[0].expirationTimeSeconds.minus(currentTimestamp).toNumber();
|
||||
await increaseTimeAndMineBlockAsync(timeUntilExpiration);
|
||||
const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
|
||||
expect(ordersInfo.length).to.be.equal(3);
|
||||
_.forEach(signedOrders, (signedOrder, index) => {
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.EXPIRED;
|
||||
const orderInfo = ordersInfo[index];
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
it('should get the correct information for multiple expired and partially filled orders', async () => {
|
||||
const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
|
||||
await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const timeUntilExpiration = signedOrders[0].expirationTimeSeconds.minus(currentTimestamp).toNumber();
|
||||
await increaseTimeAndMineBlockAsync(timeUntilExpiration);
|
||||
const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
|
||||
expect(ordersInfo.length).to.be.equal(3);
|
||||
_.forEach(signedOrders, (signedOrder, index) => {
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
|
||||
const expectedOrderStatus = OrderStatus.EXPIRED;
|
||||
const orderInfo = ordersInfo[index];
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
it('should get the correct information for a mix of unfilled, partially filled, fully filled, cancelled, and expired orders', async () => {
|
||||
const unfilledOrder = await orderFactory.newSignedOrderAsync();
|
||||
const partiallyFilledOrder = await orderFactory.newSignedOrderAsync();
|
||||
await exchangeWrapper.fillOrderAsync(partiallyFilledOrder, takerAddress, {
|
||||
takerAssetFillAmount: partiallyFilledOrder.takerAssetAmount.div(2),
|
||||
});
|
||||
const fullyFilledOrder = await orderFactory.newSignedOrderAsync();
|
||||
await exchangeWrapper.fillOrderAsync(fullyFilledOrder, takerAddress);
|
||||
const cancelledOrder = await orderFactory.newSignedOrderAsync();
|
||||
await exchangeWrapper.cancelOrderAsync(cancelledOrder, makerAddress);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const expiredOrder = await orderFactory.newSignedOrderAsync({
|
||||
expirationTimeSeconds: new BigNumber(currentTimestamp),
|
||||
});
|
||||
signedOrders = [unfilledOrder, partiallyFilledOrder, fullyFilledOrder, cancelledOrder, expiredOrder];
|
||||
const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
|
||||
expect(ordersInfo.length).to.be.equal(5);
|
||||
|
||||
const expectedUnfilledOrderHash = orderHashUtils.getOrderHashHex(unfilledOrder);
|
||||
const expectedUnfilledTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedUnfilledOrderStatus = OrderStatus.FILLABLE;
|
||||
const unfilledOrderInfo = ordersInfo[0];
|
||||
expect(unfilledOrderInfo.orderHash).to.be.equal(expectedUnfilledOrderHash);
|
||||
expect(unfilledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
|
||||
expectedUnfilledTakerAssetFilledAmount,
|
||||
);
|
||||
expect(unfilledOrderInfo.orderStatus).to.be.equal(expectedUnfilledOrderStatus);
|
||||
|
||||
const expectedPartialOrderHash = orderHashUtils.getOrderHashHex(partiallyFilledOrder);
|
||||
const expectedPartialTakerAssetFilledAmount = partiallyFilledOrder.takerAssetAmount.div(2);
|
||||
const expectedPartialOrderStatus = OrderStatus.FILLABLE;
|
||||
const partialOrderInfo = ordersInfo[1];
|
||||
expect(partialOrderInfo.orderHash).to.be.equal(expectedPartialOrderHash);
|
||||
expect(partialOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
|
||||
expectedPartialTakerAssetFilledAmount,
|
||||
);
|
||||
expect(partialOrderInfo.orderStatus).to.be.equal(expectedPartialOrderStatus);
|
||||
|
||||
const expectedFilledOrderHash = orderHashUtils.getOrderHashHex(fullyFilledOrder);
|
||||
const expectedFilledTakerAssetFilledAmount = fullyFilledOrder.takerAssetAmount;
|
||||
const expectedFilledOrderStatus = OrderStatus.FULLY_FILLED;
|
||||
const filledOrderInfo = ordersInfo[2];
|
||||
expect(filledOrderInfo.orderHash).to.be.equal(expectedFilledOrderHash);
|
||||
expect(filledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
|
||||
expectedFilledTakerAssetFilledAmount,
|
||||
);
|
||||
expect(filledOrderInfo.orderStatus).to.be.equal(expectedFilledOrderStatus);
|
||||
|
||||
const expectedCancelledOrderHash = orderHashUtils.getOrderHashHex(cancelledOrder);
|
||||
const expectedCancelledTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedCancelledOrderStatus = OrderStatus.CANCELLED;
|
||||
const cancelledOrderInfo = ordersInfo[3];
|
||||
expect(cancelledOrderInfo.orderHash).to.be.equal(expectedCancelledOrderHash);
|
||||
expect(cancelledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
|
||||
expectedCancelledTakerAssetFilledAmount,
|
||||
);
|
||||
expect(cancelledOrderInfo.orderStatus).to.be.equal(expectedCancelledOrderStatus);
|
||||
|
||||
const expectedExpiredOrderHash = orderHashUtils.getOrderHashHex(expiredOrder);
|
||||
const expectedExpiredTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedExpiredOrderStatus = OrderStatus.EXPIRED;
|
||||
const expiredOrderInfo = ordersInfo[4];
|
||||
expect(expiredOrderInfo.orderHash).to.be.equal(expectedExpiredOrderHash);
|
||||
expect(expiredOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
|
||||
expectedExpiredTakerAssetFilledAmount,
|
||||
);
|
||||
expect(expiredOrderInfo.orderStatus).to.be.equal(expectedExpiredOrderStatus);
|
||||
});
|
||||
});
|
||||
});
|
||||
}); // tslint:disable-line:max-file-line-count
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId, RevertReason, SignedOrder } from '@0xproject/types';
|
||||
import { assetDataUtils } from '@0xproject/order-utils';
|
||||
import { RevertReason, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
@@ -88,8 +88,8 @@ describe(ContractName.Forwarder, () => {
|
||||
weth = new DummyERC20TokenContract(wethContract.abi, wethContract.address, provider);
|
||||
erc20Wrapper.addDummyTokenContract(weth);
|
||||
|
||||
const wethAssetData = assetProxyUtils.encodeERC20AssetData(wethContract.address);
|
||||
const zrxAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
||||
const wethAssetData = assetDataUtils.encodeERC20AssetData(wethContract.address);
|
||||
const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
|
||||
const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync(
|
||||
artifacts.Exchange,
|
||||
provider,
|
||||
@@ -114,8 +114,8 @@ describe(ContractName.Forwarder, () => {
|
||||
exchangeAddress: exchangeInstance.address,
|
||||
makerAddress,
|
||||
feeRecipientAddress,
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), DECIMALS_DEFAULT),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT),
|
||||
makerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
@@ -131,7 +131,6 @@ describe(ContractName.Forwarder, () => {
|
||||
exchangeInstance.address,
|
||||
wethContract.address,
|
||||
zrxToken.address,
|
||||
AssetProxyId.ERC20,
|
||||
zrxAssetData,
|
||||
wethAssetData,
|
||||
);
|
||||
@@ -149,14 +148,14 @@ describe(ContractName.Forwarder, () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
feeProportion = 0;
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
signedOrders = [signedOrder];
|
||||
feeOrder = orderFactory.newSignedOrder({
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
feeOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
});
|
||||
feeOrders = [feeOrder];
|
||||
orderWithFee = orderFactory.newSignedOrder({
|
||||
orderWithFee = await orderFactory.newSignedOrderAsync({
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
});
|
||||
signedOrdersWithFee = [orderWithFee];
|
||||
@@ -239,8 +238,8 @@ describe(ContractName.Forwarder, () => {
|
||||
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(new BigNumber(0));
|
||||
});
|
||||
it('should fill the order when token is ZRX with fees', async () => {
|
||||
orderWithFee = orderFactory.newSignedOrder({
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
orderWithFee = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
});
|
||||
signedOrdersWithFee = [orderWithFee];
|
||||
@@ -261,8 +260,8 @@ describe(ContractName.Forwarder, () => {
|
||||
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(new BigNumber(0));
|
||||
});
|
||||
it('should fail if sent an ETH amount too high', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
});
|
||||
const fillAmount = signedOrder.takerAssetAmount.times(2);
|
||||
@@ -275,12 +274,12 @@ describe(ContractName.Forwarder, () => {
|
||||
);
|
||||
});
|
||||
it('should fail if fee abstraction amount is too high', async () => {
|
||||
orderWithFee = orderFactory.newSignedOrder({
|
||||
orderWithFee = await orderFactory.newSignedOrderAsync({
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), DECIMALS_DEFAULT),
|
||||
});
|
||||
signedOrdersWithFee = [orderWithFee];
|
||||
feeOrder = orderFactory.newSignedOrder({
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
feeOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
});
|
||||
feeOrders = [feeOrder];
|
||||
@@ -295,11 +294,11 @@ describe(ContractName.Forwarder, () => {
|
||||
});
|
||||
it('throws when mixed ERC721 and ERC20 assets with ERC20 first', async () => {
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const erc721SignedOrder = orderFactory.newSignedOrder({
|
||||
const erc721SignedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
});
|
||||
const erc20SignedOrder = orderFactory.newSignedOrder();
|
||||
const erc20SignedOrder = await orderFactory.newSignedOrderAsync();
|
||||
signedOrders = [erc20SignedOrder, erc721SignedOrder];
|
||||
const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount);
|
||||
return expectTransactionFailedAsync(
|
||||
@@ -419,8 +418,8 @@ describe(ContractName.Forwarder, () => {
|
||||
expect(takerBalanceAfter).to.be.bignumber.eq(takerBalanceBefore.plus(makerAssetAmount));
|
||||
});
|
||||
it('should buy the exact amount of assets when buying zrx with fee abstraction', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
});
|
||||
signedOrdersWithFee = [signedOrder];
|
||||
@@ -448,8 +447,8 @@ describe(ContractName.Forwarder, () => {
|
||||
expect(takerWeiBalanceAfter).to.be.bignumber.equal(takerWeiBalanceBefore.minus(expectedCostAfterGas));
|
||||
});
|
||||
it('throws if fees are higher than 5% when buying zrx', async () => {
|
||||
const highFeeZRXOrder = orderFactory.newSignedOrder({
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
const highFeeZRXOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
makerAssetAmount: signedOrder.makerAssetAmount,
|
||||
takerFee: signedOrder.makerAssetAmount.times(0.06),
|
||||
});
|
||||
@@ -471,7 +470,7 @@ describe(ContractName.Forwarder, () => {
|
||||
);
|
||||
});
|
||||
it('throws if fees are higher than 5% when buying erc20', async () => {
|
||||
const highFeeERC20Order = orderFactory.newSignedOrder({
|
||||
const highFeeERC20Order = await orderFactory.newSignedOrderAsync({
|
||||
takerFee: signedOrder.makerAssetAmount.times(0.06),
|
||||
});
|
||||
signedOrdersWithFee = [highFeeERC20Order];
|
||||
@@ -545,9 +544,9 @@ describe(ContractName.Forwarder, () => {
|
||||
describe('marketBuyTokensWithEth - ERC721', async () => {
|
||||
it('buys ERC721 assets', async () => {
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
});
|
||||
feeOrders = [];
|
||||
signedOrders = [signedOrder];
|
||||
@@ -567,10 +566,10 @@ describe(ContractName.Forwarder, () => {
|
||||
});
|
||||
it('buys ERC721 assets with fee abstraction', async () => {
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
});
|
||||
signedOrders = [signedOrder];
|
||||
const makerAssetAmount = new BigNumber(signedOrders.length);
|
||||
@@ -589,10 +588,10 @@ describe(ContractName.Forwarder, () => {
|
||||
});
|
||||
it('buys ERC721 assets with fee abstraction and pays fee to fee recipient', async () => {
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
});
|
||||
signedOrders = [signedOrder];
|
||||
feeProportion = 100;
|
||||
@@ -631,15 +630,15 @@ describe(ContractName.Forwarder, () => {
|
||||
it('buys multiple ERC721 assets with fee abstraction and pays fee to fee recipient', async () => {
|
||||
const makerAssetId1 = erc721MakerAssetIds[0];
|
||||
const makerAssetId2 = erc721MakerAssetIds[1];
|
||||
const signedOrder1 = orderFactory.newSignedOrder({
|
||||
const signedOrder1 = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(3), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId1),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId1),
|
||||
});
|
||||
const signedOrder2 = orderFactory.newSignedOrder({
|
||||
const signedOrder2 = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(4), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId2),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId2),
|
||||
});
|
||||
signedOrders = [signedOrder1, signedOrder2];
|
||||
feeProportion = 10;
|
||||
@@ -666,23 +665,23 @@ describe(ContractName.Forwarder, () => {
|
||||
// There are two fee orders, but the first fee order is partially filled while
|
||||
// the Forwarding contract tx is in the mempool.
|
||||
const erc721MakerAssetAmount = new BigNumber(1);
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: erc721MakerAssetAmount,
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(6), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
});
|
||||
signedOrders = [signedOrder];
|
||||
const firstFeeOrder = orderFactory.newSignedOrder({
|
||||
const firstFeeOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.1), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT),
|
||||
});
|
||||
const secondFeeOrder = orderFactory.newSignedOrder({
|
||||
const secondFeeOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.12), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT),
|
||||
});
|
||||
feeOrders = [firstFeeOrder, secondFeeOrder];
|
||||
@@ -730,24 +729,24 @@ describe(ContractName.Forwarder, () => {
|
||||
// There are two fee orders, but the first fee order is partially filled while
|
||||
// the Forwarding contract tx is in the mempool.
|
||||
const erc721MakerAssetAmount = new BigNumber(1);
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: erc721MakerAssetAmount,
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(6), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
});
|
||||
const zrxMakerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT);
|
||||
signedOrders = [signedOrder];
|
||||
const firstFeeOrder = orderFactory.newSignedOrder({
|
||||
const firstFeeOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: zrxMakerAssetAmount,
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.1), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT),
|
||||
});
|
||||
const secondFeeOrder = orderFactory.newSignedOrder({
|
||||
const secondFeeOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: zrxMakerAssetAmount,
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.12), DECIMALS_DEFAULT),
|
||||
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
|
||||
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT),
|
||||
});
|
||||
feeOrders = [firstFeeOrder, secondFeeOrder];
|
||||
@@ -779,11 +778,11 @@ describe(ContractName.Forwarder, () => {
|
||||
});
|
||||
it('throws when mixed ERC721 and ERC20 assets', async () => {
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const erc721SignedOrder = orderFactory.newSignedOrder({
|
||||
const erc721SignedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
});
|
||||
const erc20SignedOrder = orderFactory.newSignedOrder();
|
||||
const erc20SignedOrder = await orderFactory.newSignedOrderAsync();
|
||||
signedOrders = [erc721SignedOrder, erc20SignedOrder];
|
||||
const makerAssetAmount = new BigNumber(signedOrders.length);
|
||||
const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount);
|
||||
@@ -797,11 +796,11 @@ describe(ContractName.Forwarder, () => {
|
||||
});
|
||||
it('throws when mixed ERC721 and ERC20 assets with ERC20 first', async () => {
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const erc721SignedOrder = orderFactory.newSignedOrder({
|
||||
const erc721SignedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
});
|
||||
const erc20SignedOrder = orderFactory.newSignedOrder();
|
||||
const erc20SignedOrder = await orderFactory.newSignedOrderAsync();
|
||||
signedOrders = [erc20SignedOrder, erc721SignedOrder];
|
||||
const makerAssetAmount = new BigNumber(signedOrders.length);
|
||||
const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { RevertReason } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import BN = require('bn.js');
|
||||
@@ -12,6 +12,7 @@ import { artifacts } from '../utils/artifacts';
|
||||
import { expectContractCallFailed } from '../utils/assertions';
|
||||
import { chaiSetup } from '../utils/chai_setup';
|
||||
import { constants } from '../utils/constants';
|
||||
import { typeEncodingUtils } from '../utils/type_encoding_utils';
|
||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -74,20 +75,20 @@ describe('LibBytes', () => {
|
||||
shortData = '0xffffaa';
|
||||
const encodedShortData = ethUtil.toBuffer(shortData);
|
||||
const shortDataLength = new BigNumber(encodedShortData.byteLength);
|
||||
const encodedShortDataLength = assetProxyUtils.encodeUint256(shortDataLength);
|
||||
const encodedShortDataLength = typeEncodingUtils.encodeUint256(shortDataLength);
|
||||
shortTestBytesAsBuffer = Buffer.concat([encodedShortDataLength, encodedShortData]);
|
||||
shortTestBytes = ethUtil.bufferToHex(shortTestBytesAsBuffer);
|
||||
// Create test bytes one word in length
|
||||
wordOfData = ethUtil.bufferToHex(assetProxyUtils.encodeUint256(generatePseudoRandomSalt()));
|
||||
wordOfData = ethUtil.bufferToHex(typeEncodingUtils.encodeUint256(generatePseudoRandomSalt()));
|
||||
const encodedWordOfData = ethUtil.toBuffer(wordOfData);
|
||||
const wordOfDataLength = new BigNumber(encodedWordOfData.byteLength);
|
||||
const encodedWordOfDataLength = assetProxyUtils.encodeUint256(wordOfDataLength);
|
||||
const encodedWordOfDataLength = typeEncodingUtils.encodeUint256(wordOfDataLength);
|
||||
wordOfTestBytesAsBuffer = Buffer.concat([encodedWordOfDataLength, encodedWordOfData]);
|
||||
wordOfTestBytes = ethUtil.bufferToHex(wordOfTestBytesAsBuffer);
|
||||
// Create long test bytes (combines short test bytes with word of test bytes)
|
||||
longData = ethUtil.bufferToHex(Buffer.concat([encodedShortData, encodedWordOfData]));
|
||||
const longDataLength = new BigNumber(encodedShortData.byteLength + encodedWordOfData.byteLength);
|
||||
const encodedLongDataLength = assetProxyUtils.encodeUint256(longDataLength);
|
||||
const encodedLongDataLength = typeEncodingUtils.encodeUint256(longDataLength);
|
||||
longTestBytesAsBuffer = Buffer.concat([encodedLongDataLength, encodedShortData, encodedWordOfData]);
|
||||
longTestBytes = ethUtil.bufferToHex(longTestBytesAsBuffer);
|
||||
});
|
||||
|
@@ -18,9 +18,9 @@ import {
|
||||
expectContractCreationFailedWithoutReason,
|
||||
expectTransactionFailedWithoutReasonAsync,
|
||||
} from '../utils/assertions';
|
||||
import { increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
|
||||
import { chaiSetup } from '../utils/chai_setup';
|
||||
import { constants } from '../utils/constants';
|
||||
import { increaseTimeAndMineBlockAsync } from '../utils/increase_time';
|
||||
import { MultiSigWrapper } from '../utils/multi_sig_wrapper';
|
||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||
|
||||
@@ -148,6 +148,25 @@ describe('AssetProxyOwner', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('readBytes4', () => {
|
||||
it('should revert if byte array has a length < 4', async () => {
|
||||
const byteArrayLessThan4Bytes = '0x010101';
|
||||
return expectContractCallFailedWithoutReasonAsync(
|
||||
testAssetProxyOwner.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, new BigNumber(0)),
|
||||
);
|
||||
});
|
||||
it('should return the first 4 bytes of a byte array of arbitrary length', async () => {
|
||||
const byteArrayLongerThan32Bytes =
|
||||
'0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
||||
const first4Bytes = await testAssetProxyOwner.publicReadBytes4.callAsync(
|
||||
byteArrayLongerThan32Bytes,
|
||||
new BigNumber(0),
|
||||
);
|
||||
const expectedFirst4Bytes = byteArrayLongerThan32Bytes.slice(0, 10);
|
||||
expect(first4Bytes).to.equal(expectedFirst4Bytes);
|
||||
});
|
||||
});
|
||||
|
||||
describe('registerAssetProxy', () => {
|
||||
it('should throw if not called by multisig', async () => {
|
||||
const isRegistered = true;
|
||||
@@ -238,8 +257,6 @@ describe('AssetProxyOwner', () => {
|
||||
const registerAssetProxySubmitLog = registerAssetProxySubmitRes.logs[0] as LogWithDecodedArgs<
|
||||
AssetProxyOwnerSubmissionEventArgs
|
||||
>;
|
||||
const registerAssetProxyTxId = registerAssetProxySubmitLog.args.transactionId;
|
||||
await multiSigWrapper.confirmTransactionAsync(registerAssetProxyTxId, owners[1]);
|
||||
|
||||
const addAuthorizedAddressData = erc20Proxy.addAuthorizedAddress.getABIEncodedTransactionData(authorized);
|
||||
const erc20AddAuthorizedAddressSubmitRes = await multiSigWrapper.submitTransactionAsync(
|
||||
@@ -257,9 +274,12 @@ describe('AssetProxyOwner', () => {
|
||||
>;
|
||||
const erc721AddAuthorizedAddressSubmitLog = erc721AddAuthorizedAddressSubmitRes
|
||||
.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>;
|
||||
|
||||
const registerAssetProxyTxId = registerAssetProxySubmitLog.args.transactionId;
|
||||
const erc20AddAuthorizedAddressTxId = erc20AddAuthorizedAddressSubmitLog.args.transactionId;
|
||||
const erc721AddAuthorizedAddressTxId = erc721AddAuthorizedAddressSubmitLog.args.transactionId;
|
||||
|
||||
await multiSigWrapper.confirmTransactionAsync(registerAssetProxyTxId, owners[1]);
|
||||
await multiSigWrapper.confirmTransactionAsync(erc20AddAuthorizedAddressTxId, owners[1]);
|
||||
await multiSigWrapper.confirmTransactionAsync(erc721AddAuthorizedAddressTxId, owners[1]);
|
||||
await increaseTimeAndMineBlockAsync(SECONDS_TIME_LOCKED.toNumber());
|
||||
|
@@ -9,9 +9,9 @@ import {
|
||||
} from '../../generated_contract_wrappers/multi_sig_wallet_with_time_lock';
|
||||
import { artifacts } from '../utils/artifacts';
|
||||
import { expectTransactionFailedWithoutReasonAsync } from '../utils/assertions';
|
||||
import { increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
|
||||
import { chaiSetup } from '../utils/chai_setup';
|
||||
import { constants } from '../utils/constants';
|
||||
import { increaseTimeAndMineBlockAsync } from '../utils/increase_time';
|
||||
import { MultiSigWrapper } from '../utils/multi_sig_wrapper';
|
||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { assetProxyUtils } from '@0xproject/order-utils';
|
||||
import { assetDataUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId } from '@0xproject/types';
|
||||
import { BigNumber, errorUtils } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
@@ -17,7 +17,7 @@ interface ProxyIdToAssetWrappers {
|
||||
* the logic that uses it does not need to care what standard a token belongs to.
|
||||
*/
|
||||
export class AssetWrapper {
|
||||
private _proxyIdToAssetWrappers: ProxyIdToAssetWrappers;
|
||||
private readonly _proxyIdToAssetWrappers: ProxyIdToAssetWrappers;
|
||||
constructor(assetWrappers: AbstractAssetWrapper[]) {
|
||||
this._proxyIdToAssetWrappers = {};
|
||||
_.each(assetWrappers, assetWrapper => {
|
||||
@@ -26,7 +26,7 @@ export class AssetWrapper {
|
||||
});
|
||||
}
|
||||
public async getBalanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
|
||||
const proxyId = assetProxyUtils.decodeAssetDataId(assetData);
|
||||
const proxyId = assetDataUtils.decodeAssetProxyId(assetData);
|
||||
switch (proxyId) {
|
||||
case AssetProxyId.ERC20: {
|
||||
const erc20Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC20Wrapper;
|
||||
@@ -35,7 +35,7 @@ export class AssetWrapper {
|
||||
}
|
||||
case AssetProxyId.ERC721: {
|
||||
const assetWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper;
|
||||
const assetProxyData = assetProxyUtils.decodeERC721AssetData(assetData);
|
||||
const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData);
|
||||
const isOwner = await assetWrapper.isOwnerAsync(
|
||||
userAddress,
|
||||
assetProxyData.tokenAddress,
|
||||
@@ -49,7 +49,7 @@ export class AssetWrapper {
|
||||
}
|
||||
}
|
||||
public async setBalanceAsync(userAddress: string, assetData: string, desiredBalance: BigNumber): Promise<void> {
|
||||
const proxyId = assetProxyUtils.decodeAssetDataId(assetData);
|
||||
const proxyId = assetDataUtils.decodeAssetProxyId(assetData);
|
||||
switch (proxyId) {
|
||||
case AssetProxyId.ERC20: {
|
||||
const erc20Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC20Wrapper;
|
||||
@@ -61,7 +61,7 @@ export class AssetWrapper {
|
||||
throw new Error(`Balance for ERC721 token can only be set to 0 or 1. Got: ${desiredBalance}`);
|
||||
}
|
||||
const erc721Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper;
|
||||
const assetProxyData = assetProxyUtils.decodeERC721AssetData(assetData);
|
||||
const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData);
|
||||
const doesTokenExist = erc721Wrapper.doesTokenExistAsync(
|
||||
assetProxyData.tokenAddress,
|
||||
assetProxyData.tokenId,
|
||||
@@ -107,7 +107,7 @@ export class AssetWrapper {
|
||||
}
|
||||
}
|
||||
public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
|
||||
const proxyId = assetProxyUtils.decodeAssetDataId(assetData);
|
||||
const proxyId = assetDataUtils.decodeAssetProxyId(assetData);
|
||||
switch (proxyId) {
|
||||
case AssetProxyId.ERC20: {
|
||||
const erc20Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC20Wrapper;
|
||||
@@ -116,7 +116,7 @@ export class AssetWrapper {
|
||||
}
|
||||
case AssetProxyId.ERC721: {
|
||||
const assetWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper;
|
||||
const erc721ProxyData = assetProxyUtils.decodeERC721AssetData(assetData);
|
||||
const erc721ProxyData = assetDataUtils.decodeERC721AssetData(assetData);
|
||||
const isProxyApprovedForAll = await assetWrapper.isProxyApprovedForAllAsync(
|
||||
userAddress,
|
||||
erc721ProxyData.tokenAddress,
|
||||
@@ -141,7 +141,7 @@ export class AssetWrapper {
|
||||
assetData: string,
|
||||
desiredAllowance: BigNumber,
|
||||
): Promise<void> {
|
||||
const proxyId = assetProxyUtils.decodeAssetDataId(assetData);
|
||||
const proxyId = assetDataUtils.decodeAssetProxyId(assetData);
|
||||
switch (proxyId) {
|
||||
case AssetProxyId.ERC20: {
|
||||
const erc20Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC20Wrapper;
|
||||
@@ -159,7 +159,7 @@ export class AssetWrapper {
|
||||
);
|
||||
}
|
||||
const erc721Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper;
|
||||
const assetProxyData = assetProxyUtils.decodeERC721AssetData(assetData);
|
||||
const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData);
|
||||
|
||||
const doesTokenExist = await erc721Wrapper.doesTokenExistAsync(
|
||||
assetProxyData.tokenAddress,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user