Compare commits
334 Commits
@0x/contra
...
@0x/contra
Author | SHA1 | Date | |
---|---|---|---|
|
6b0f3570b9 | ||
|
71de0d04f3 | ||
|
99debff5d2 | ||
|
3bac6fcb27 | ||
|
4b842b81a0 | ||
|
e2e4d048ab | ||
|
5574c368cd | ||
|
0d34f7b92e | ||
|
5be0632e01 | ||
|
79ea0bf9f4 | ||
|
b1929cb688 | ||
|
5ad98700e5 | ||
|
a54624b697 | ||
|
ca34c865af | ||
|
dde57b1eca | ||
|
264b06938e | ||
|
99edb303e2 | ||
|
104cc24dfc | ||
|
fcbcbac889 | ||
|
b86d19028c | ||
|
4f17a251d3 | ||
|
3d79fe2bf4 | ||
|
474399154f | ||
|
19f5153d0e | ||
|
ce11271866 | ||
|
86cf353296 | ||
|
36df5dc721 | ||
|
1e44a9c942 | ||
|
8685cf9036 | ||
|
2232870b09 | ||
|
b68acd101e | ||
|
173ba9b2b5 | ||
|
64ed1f87d3 | ||
|
1ca085ec4a | ||
|
e332b7535c | ||
|
79eb613b3e | ||
|
5a79ec28d1 | ||
|
97e65a02c0 | ||
|
e87c786b77 | ||
|
251d30d47f | ||
|
761d0a0f18 | ||
|
ae4b1e74f9 | ||
|
ac44618e58 | ||
|
d634cbf924 | ||
|
21db0e6275 | ||
|
ce426fd3f4 | ||
|
b5d4c91207 | ||
|
b43263be77 | ||
|
207cf7ca24 | ||
|
00e34758c4 | ||
|
7a3f878c11 | ||
|
b8439598bc | ||
|
7fb0818923 | ||
|
a7c435adc4 | ||
|
dd90aabad6 | ||
|
5bded1946e | ||
|
3642e96154 | ||
|
9da09ee3a6 | ||
|
141c140f53 | ||
|
84b660d2ef | ||
|
6beedba957 | ||
|
d73982819b | ||
|
6ac5bcc907 | ||
|
389d4d10f1 | ||
|
89dcbd0229 | ||
|
ad8caa2b51 | ||
|
9c42241269 | ||
|
38dd45cce2 | ||
|
aa90253c62 | ||
|
41576652dc | ||
|
74830854ca | ||
|
2542b1b44d | ||
|
51f5e60224 | ||
|
bb5885e2bb | ||
|
d51bbb0008 | ||
|
49e898b189 | ||
|
42c4fe5705 | ||
|
4b5f2c36b9 | ||
|
935dca67e6 | ||
|
d431790e19 | ||
|
56310b7bd4 | ||
|
f15e21faad | ||
|
44aa6a2b38 | ||
|
9f32347c01 | ||
|
3d5b229c46 | ||
|
5863ccc0a0 | ||
|
d220a16b99 | ||
|
79784fc8ee | ||
|
a83bc53c6a | ||
|
85de0b91b1 | ||
|
d91c6e5702 | ||
|
ab7689d188 | ||
|
c81455c760 | ||
|
39bfc97a7a | ||
|
88aac78282 | ||
|
863e830d24 | ||
|
6c705728a4 | ||
|
7f00279ffb | ||
|
c198d0079e | ||
|
1135d5a971 | ||
|
e299fa27a0 | ||
|
46e0bc940a | ||
|
9a552012f2 | ||
|
6498d385ee | ||
|
dd00f2016f | ||
|
64d25e6522 | ||
|
1462ab08de | ||
|
a8e93a594d | ||
|
dea30b37ef | ||
|
39571dda0b | ||
|
c7d801b6c2 | ||
|
57731be689 | ||
|
f00524e518 | ||
|
5567c40bae | ||
|
5d1a7613dd | ||
|
fa768dc112 | ||
|
27fb51d37f | ||
|
d02db3864e | ||
|
a26c3036a7 | ||
|
0af346aad8 | ||
|
c3c8ee7292 | ||
|
5fbdfa66d9 | ||
|
15b75715ee | ||
|
1fd92b6cbd | ||
|
2918b5d74e | ||
|
669c5be344 | ||
|
e1b40ec46e | ||
|
15767538eb | ||
|
de2b16c464 | ||
|
d5e6b38450 | ||
|
a636e87a4f | ||
|
50d5b4fa37 | ||
|
f6d26392fb | ||
|
2705bcce15 | ||
|
379a31ece6 | ||
|
daa593d225 | ||
|
ed8340affa | ||
|
b3c1e72577 | ||
|
3da09d140a | ||
|
51f254bbb1 | ||
|
30ee456d4c | ||
|
460d5f2517 | ||
|
5da1fc8445 | ||
|
1166b43946 | ||
|
0a6903c4c3 | ||
|
62fae9af93 | ||
|
509a1c2eb5 | ||
|
8b94bbbc5e | ||
|
bb923d2b7d | ||
|
38adc72954 | ||
|
362c7c57fa | ||
|
6529b7eebf | ||
|
439c98a6e5 | ||
|
32258ef666 | ||
|
176e088d4e | ||
|
4fe57ba025 | ||
|
2818e56932 | ||
|
5428a19617 | ||
|
b58cbca61a | ||
|
5fc6a03784 | ||
|
eb4ad0ba1b | ||
|
72cdd1ea50 | ||
|
18769f0b8f | ||
|
b7d92c3c12 | ||
|
b976101dca | ||
|
8943b670a4 | ||
|
c92ff7c622 | ||
|
301b5e1721 | ||
|
4e50b9b479 | ||
|
f8b7b8cc28 | ||
|
2a6ea74be7 | ||
|
6d6a0c12cd | ||
|
784a03300a | ||
|
392f578567 | ||
|
a91b1d2dd2 | ||
|
400b3d961e | ||
|
4f128470bd | ||
|
fe06f41136 | ||
|
f81a99565e | ||
|
81e146650b | ||
|
bd4e04d331 | ||
|
7663d2c64b | ||
|
443c3c2802 | ||
|
17a546af5d | ||
|
71faf46735 | ||
|
ac28744df6 | ||
|
adaf304b4e | ||
|
16b13f9768 | ||
|
d64bf98dc0 | ||
|
71f57d13fa | ||
|
469c10e45f | ||
|
62def596af | ||
|
aa10844d9e | ||
|
be52079182 | ||
|
255aca8789 | ||
|
117f4a282d | ||
|
e1ea65525f | ||
|
d0a3495b5f | ||
|
9e9e0d6592 | ||
|
cb5f9ba97d | ||
|
34538f2ced | ||
|
2575644920 | ||
|
b4b43a9e9e | ||
|
df97b20913 | ||
|
9e3cc379ed | ||
|
c1d78a94a2 | ||
|
7f4cbba076 | ||
|
bdca84fe72 | ||
|
cf8fd7103b | ||
|
8e8cdbd413 | ||
|
30f01681d4 | ||
|
ecf1ad8da1 | ||
|
42dc112a13 | ||
|
58276cefce | ||
|
4b6501a739 | ||
|
724085e068 | ||
|
21fab3ef9f | ||
|
db8837f4ce | ||
|
5781cdf6da | ||
|
874eb1602f | ||
|
82149917b7 | ||
|
f11d8a5bd8 | ||
|
f0d7d10fe7 | ||
|
9d4d9ce978 | ||
|
96a38602b8 | ||
|
90d3558d31 | ||
|
e491a56dd0 | ||
|
4d8eb61924 | ||
|
17fab541c6 | ||
|
91de35e8e9 | ||
|
f61964676a | ||
|
41a34c19bb | ||
|
d90810d127 | ||
|
7f3d281faa | ||
|
812c306805 | ||
|
fc1c59f374 | ||
|
35eac1e3ff | ||
|
e16041d7fa | ||
|
b8fc84ecc8 | ||
|
572c576e15 | ||
|
9df7f80fbb | ||
|
f003400135 | ||
|
ca7616c1d2 | ||
|
a4a2bfdf35 | ||
|
eb6bbb6e78 | ||
|
4d0172f634 | ||
|
3b61e0e126 | ||
|
1540a91835 | ||
|
2bcce9eed0 | ||
|
1e53564386 | ||
|
d1c72706ef | ||
|
bd9e531257 | ||
|
48436424db | ||
|
4f10d7f859 | ||
|
80e5a29444 | ||
|
0ec8a4a160 | ||
|
810bf7af0c | ||
|
e7825206bf | ||
|
2b887c336a | ||
|
48ecd32d5d | ||
|
1f5a0987cb | ||
|
f33a9d162a | ||
|
c2919bcdb0 | ||
|
120d554a6b | ||
|
44f268a7ee | ||
|
3c7a0bcd85 | ||
|
8e2e9e9331 | ||
|
91c26fc046 | ||
|
afcfe58add | ||
|
8d423be223 | ||
|
03b7314550 | ||
|
1a7e425780 | ||
|
8bc5faff3c | ||
|
2676278a66 | ||
|
6376b3baf3 | ||
|
e569abe740 | ||
|
71be9ef92a | ||
|
4990c4903d | ||
|
9d468e2383 | ||
|
109cac013c | ||
|
0d8a9921cd | ||
|
2a5f5f7312 | ||
|
fe54fbefbb | ||
|
fc824b8d06 | ||
|
d91a7b6d0e | ||
|
aa4b3f93fa | ||
|
efe8225d18 | ||
|
b2c0f8c158 | ||
|
66dce8794d | ||
|
30d54407e6 | ||
|
6324a92ec5 | ||
|
67e7b5c124 | ||
|
35099d9b2f | ||
|
e07f7b54e0 | ||
|
5c409929b4 | ||
|
1a504fdde9 | ||
|
4b06fd511b | ||
|
def6727286 | ||
|
bedaa0db16 | ||
|
90640a4fcf | ||
|
0142d07f10 | ||
|
c9d85cfc7d | ||
|
64304c1991 | ||
|
993adc3578 | ||
|
8813bd26f6 | ||
|
35925de320 | ||
|
3b426a3f07 | ||
|
5104fd5dcf | ||
|
a5a9ca9e46 | ||
|
ba0f07e3b2 | ||
|
8614475324 | ||
|
744dda144b | ||
|
13d47915f4 | ||
|
3059b85e41 | ||
|
184ea4a67f | ||
|
8032f536ed | ||
|
fba3870ef1 | ||
|
2915ee08ea | ||
|
86b76a3e75 | ||
|
bc1dca3f6f | ||
|
5db1820123 | ||
|
657c35fb86 | ||
|
9432a84468 | ||
|
15a5bc02ef | ||
|
f011be9347 | ||
|
b6094fdb34 | ||
|
9e6ab9f585 | ||
|
869d2c02fa | ||
|
3b1dca0e70 | ||
|
595358fa69 | ||
|
8a8ec79c6c | ||
|
6252446bd3 | ||
|
403ceebff9 | ||
|
4767882ed3 |
@@ -37,7 +37,7 @@ jobs:
|
|||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: ~/repo/packages/abi-gen/test-cli/output
|
path: ~/repo/packages/abi-gen/test-cli/output
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: ~/repo/packages/abi-gen-wrappers/generated_docs
|
path: ~/repo/packages/contract-wrappers/generated_docs
|
||||||
test-contracts-ganache:
|
test-contracts-ganache:
|
||||||
resource_class: medium+
|
resource_class: medium+
|
||||||
docker:
|
docker:
|
||||||
@@ -77,7 +77,7 @@ jobs:
|
|||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-tests @0x/contracts-staking @0x/contracts-coordinator
|
- run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-tests @0x/contracts-staking @0x/contracts-coordinator @0x/contracts-erc20-bridge-sampler
|
||||||
# TODO(dorothy-zbornak): Re-enable after updating this package for
|
# TODO(dorothy-zbornak): Re-enable after updating this package for
|
||||||
# 3.0. At that time, also remove exclusion from monorepo
|
# 3.0. At that time, also remove exclusion from monorepo
|
||||||
# package.json's test script.
|
# package.json's test script.
|
||||||
@@ -93,8 +93,8 @@ jobs:
|
|||||||
keys:
|
keys:
|
||||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- run:
|
- run:
|
||||||
command: yarn test:publish:circleci
|
command: yarn test:publish:circleci
|
||||||
no_output_timeout: 1800
|
no_output_timeout: 1800
|
||||||
test-doc-generation:
|
test-doc-generation:
|
||||||
docker:
|
docker:
|
||||||
- image: nikolaik/python-nodejs:python3.7-nodejs8
|
- image: nikolaik/python-nodejs:python3.7-nodejs8
|
||||||
@@ -104,8 +104,8 @@ jobs:
|
|||||||
keys:
|
keys:
|
||||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- run:
|
- run:
|
||||||
command: yarn test:generate_docs:circleci
|
command: yarn test:generate_docs:circleci
|
||||||
no_output_timeout: 1200
|
no_output_timeout: 1200
|
||||||
test-rest:
|
test-rest:
|
||||||
docker:
|
docker:
|
||||||
- image: nikolaik/python-nodejs:python3.7-nodejs8
|
- image: nikolaik/python-nodejs:python3.7-nodejs8
|
||||||
@@ -116,23 +116,16 @@ jobs:
|
|||||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- run: yarn wsrun test:circleci @0x/contracts-test-utils
|
- run: yarn wsrun test:circleci @0x/contracts-test-utils
|
||||||
- run: yarn wsrun test:circleci @0x/abi-gen
|
- run: yarn wsrun test:circleci @0x/abi-gen
|
||||||
# TODO (xianny): Needs to be updated for 3.0
|
- run: yarn wsrun test:circleci @0x/asset-swapper
|
||||||
# - run: yarn wsrun test:circleci @0x/asset-buyer
|
|
||||||
# TODO: Needs to be updated for 3.0. At that time, also remove
|
|
||||||
# exclusion from monorepo package.json's test script.
|
|
||||||
# - run: yarn wsrun test:circleci @0x/asset-swapper
|
|
||||||
- run: yarn wsrun test:circleci @0x/contract-artifacts
|
- run: yarn wsrun test:circleci @0x/contract-artifacts
|
||||||
- run: yarn wsrun test:circleci @0x/assert
|
- run: yarn wsrun test:circleci @0x/assert
|
||||||
- run: yarn wsrun test:circleci @0x/base-contract
|
- run: yarn wsrun test:circleci @0x/base-contract
|
||||||
# TODO (xianny): Needs to be updated for 3.0
|
- run: yarn wsrun test:circleci @0x/connect
|
||||||
# - run: yarn wsrun test:circleci @0x/connect
|
- run: yarn wsrun test:circleci @0x/contract-wrappers-test
|
||||||
- run: yarn wsrun test:circleci @0x/contract-wrappers
|
|
||||||
- run: yarn wsrun test:circleci @0x/dev-utils
|
- run: yarn wsrun test:circleci @0x/dev-utils
|
||||||
- run: yarn wsrun test:circleci @0x/json-schemas
|
- run: yarn wsrun test:circleci @0x/json-schemas
|
||||||
- run: yarn wsrun test:circleci @0x/order-utils
|
- run: yarn wsrun test:circleci @0x/order-utils
|
||||||
# TODO: Needs to be updated for 3.0. At that time, also remove
|
- run: yarn wsrun test:circleci @0x/orderbook
|
||||||
# exclusion from monorepo package.json's test script.
|
|
||||||
# - run: yarn wsrun test:circleci @0x/orderbook
|
|
||||||
- run: yarn wsrun test:circleci @0x/sol-compiler
|
- run: yarn wsrun test:circleci @0x/sol-compiler
|
||||||
- run: yarn wsrun test:circleci @0x/sol-tracing-utils
|
- run: yarn wsrun test:circleci @0x/sol-tracing-utils
|
||||||
- run: yarn wsrun test:circleci @0x/sol-doc
|
- run: yarn wsrun test:circleci @0x/sol-doc
|
||||||
@@ -149,9 +142,9 @@ jobs:
|
|||||||
paths:
|
paths:
|
||||||
- ~/repo/packages/assert/coverage/lcov.info
|
- ~/repo/packages/assert/coverage/lcov.info
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }}
|
key: coverage-asset-swapper-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
paths:
|
paths:
|
||||||
- ~/repo/packages/asset-buyer/coverage/lcov.info
|
- ~/repo/packages/asset-swapper/coverage/lcov.info
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
|
key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
paths:
|
paths:
|
||||||
@@ -161,9 +154,9 @@ jobs:
|
|||||||
paths:
|
paths:
|
||||||
- ~/repo/packages/connect/coverage/lcov.info
|
- ~/repo/packages/connect/coverage/lcov.info
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
|
key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
paths:
|
paths:
|
||||||
- ~/repo/packages/contract-wrappers/coverage/lcov.info
|
- ~/repo/packages/contract-wrappers-test/coverage/lcov.info
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
|
key: coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
paths:
|
paths:
|
||||||
@@ -200,11 +193,8 @@ jobs:
|
|||||||
working_directory: ~/repo
|
working_directory: ~/repo
|
||||||
docker:
|
docker:
|
||||||
- image: nikolaik/python-nodejs:python3.7-nodejs8
|
- image: nikolaik/python-nodejs:python3.7-nodejs8
|
||||||
- image: 0xorg/ganache-cli:4.4.0-beta.1
|
- image: 0xorg/ganache-cli
|
||||||
environment:
|
- image: 0xorg/mesh:0xV3
|
||||||
VERSION: 4.4.0-beta.1
|
|
||||||
SNAPSHOT_NAME: 0x_ganache_snapshot-v3-beta
|
|
||||||
- image: 0xorg/mesh:6.0.0-beta-0xv3
|
|
||||||
environment:
|
environment:
|
||||||
ETHEREUM_RPC_URL: 'http://localhost:8545'
|
ETHEREUM_RPC_URL: 'http://localhost:8545'
|
||||||
ETHEREUM_NETWORK_ID: '50'
|
ETHEREUM_NETWORK_ID: '50'
|
||||||
@@ -219,14 +209,14 @@ jobs:
|
|||||||
- image: 0xorg/launch-kit-backend:v3
|
- image: 0xorg/launch-kit-backend:v3
|
||||||
environment:
|
environment:
|
||||||
RPC_URL: 'http://localhost:8545'
|
RPC_URL: 'http://localhost:8545'
|
||||||
NETWORK_ID: 50
|
CHAIN_ID: 1337
|
||||||
WHITELIST_ALL_TOKENS: True
|
WHITELIST_ALL_TOKENS: True
|
||||||
FEE_RECIPIENT: '0x0000000000000000000000000000000000000001'
|
FEE_RECIPIENT: '0x0000000000000000000000000000000000000001'
|
||||||
MAKER_FEE_UNIT_AMOUNT: 0
|
MAKER_FEE_UNIT_AMOUNT: 0
|
||||||
TAKER_FEE_UNIT_AMOUNT: 0
|
TAKER_FEE_UNIT_AMOUNT: 0
|
||||||
MESH_ENDPOINT: 'ws://localhost:60557'
|
MESH_ENDPOINT: 'ws://localhost:60557'
|
||||||
command: |
|
command: |
|
||||||
sh -c "waitForMesh () { sleep 5; }; waitForMesh && node_modules/.bin/forever ts/lib/index.js"
|
sh -c "waitForMesh () { sleep 30; }; waitForMesh && node_modules/.bin/forever ts/lib/index.js"
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
@@ -369,7 +359,7 @@ jobs:
|
|||||||
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
|
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }}
|
- coverage-asset-swapper-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
|
- coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
@@ -378,7 +368,7 @@ jobs:
|
|||||||
- coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
|
- coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
|
- coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
|
- coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
|
5
.github/autolabeler.yml
vendored
5
.github/autolabeler.yml
vendored
@@ -19,18 +19,15 @@ contracts: ['contracts']
|
|||||||
@0x/sol-tracing-utils: ['packages/sol-tracing-utils']
|
@0x/sol-tracing-utils: ['packages/sol-tracing-utils']
|
||||||
@0x/utils: ['packages/utils']
|
@0x/utils: ['packages/utils']
|
||||||
@0x/tslint-config: ['packages/tslint-config']
|
@0x/tslint-config: ['packages/tslint-config']
|
||||||
@0x/asset-buyer: ['packages/asset-buyer']
|
@0x/asset-swapper: ['packages/asset-swapper']
|
||||||
@0x/order-utils: ['packages/order-utils']
|
@0x/order-utils: ['packages/order-utils']
|
||||||
@0x/assert: ['packages/assert']
|
@0x/assert: ['packages/assert']
|
||||||
@0x/base-contract: ['packages/base-contract']
|
@0x/base-contract: ['packages/base-contract']
|
||||||
@0x/typescript-typings: ['packages/typescript-typings']
|
@0x/typescript-typings: ['packages/typescript-typings']
|
||||||
0x.js: ['packages/0x.js']
|
0x.js: ['packages/0x.js']
|
||||||
@0x/abi-gen-wrappers: ['packages/abi-gen-wrappers']
|
|
||||||
@0x/contract-artifacts: ['packages/contract-artifacts']
|
@0x/contract-artifacts: ['packages/contract-artifacts']
|
||||||
@0x/dev-utils: ['packages/dev-utils']
|
@0x/dev-utils: ['packages/dev-utils']
|
||||||
@0x/contract-wrappers: ['packages/contract-wrappers']
|
@0x/contract-wrappers: ['packages/contract-wrappers']
|
||||||
@0x/json-schemas: ['packages/json-schemas']
|
@0x/json-schemas: ['packages/json-schemas']
|
||||||
@0x/ethereum-types: ['ethereum-types']
|
@0x/ethereum-types: ['ethereum-types']
|
||||||
@0x/connect: ['packages/connect']
|
@0x/connect: ['packages/connect']
|
||||||
@0x/testnet-faucets: ['packages/testnet-faucets']
|
|
||||||
@0x/monorepo-scripts: ['packages/monorepo-scripts']
|
|
||||||
|
41
.gitignore
vendored
41
.gitignore
vendored
@@ -78,28 +78,42 @@ TODO.md
|
|||||||
# VSCode file
|
# VSCode file
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
# server cli
|
|
||||||
packages/testnet-faucets/server/
|
|
||||||
|
|
||||||
# generated contract artifacts/
|
# generated contract artifacts/
|
||||||
|
contracts/erc20-bridge-sampler/generated-artifacts/
|
||||||
|
contracts/erc20-bridge-sampler/test/generated-artifacts/
|
||||||
contracts/integrations/generated-artifacts/
|
contracts/integrations/generated-artifacts/
|
||||||
|
contracts/integrations/test/generated-artifacts/
|
||||||
contracts/staking/generated-artifacts/
|
contracts/staking/generated-artifacts/
|
||||||
|
contracts/staking/test/generated-artifacts/
|
||||||
contracts/coordinator/generated-artifacts/
|
contracts/coordinator/generated-artifacts/
|
||||||
|
contracts/coordinator/test/generated-artifacts/
|
||||||
contracts/exchange/generated-artifacts/
|
contracts/exchange/generated-artifacts/
|
||||||
|
contracts/exchange/test/generated-artifacts/
|
||||||
contracts/asset-proxy/generated-artifacts/
|
contracts/asset-proxy/generated-artifacts/
|
||||||
|
contracts/asset-proxy/test/generated-artifacts/
|
||||||
contracts/multisig/generated-artifacts/
|
contracts/multisig/generated-artifacts/
|
||||||
|
contracts/multisig/test/generated-artifacts/
|
||||||
contracts/utils/generated-artifacts/
|
contracts/utils/generated-artifacts/
|
||||||
|
contracts/utils/test/generated-artifacts/
|
||||||
contracts/exchange-libs/generated-artifacts/
|
contracts/exchange-libs/generated-artifacts/
|
||||||
|
contracts/exchange-libs/test/generated-artifacts/
|
||||||
contracts/erc20/generated-artifacts/
|
contracts/erc20/generated-artifacts/
|
||||||
|
contracts/erc20/test/generated-artifacts/
|
||||||
contracts/erc721/generated-artifacts/
|
contracts/erc721/generated-artifacts/
|
||||||
|
contracts/erc721/test/generated-artifacts/
|
||||||
contracts/erc1155/generated-artifacts/
|
contracts/erc1155/generated-artifacts/
|
||||||
|
contracts/erc1155/test/generated-artifacts/
|
||||||
contracts/extensions/generated-artifacts/
|
contracts/extensions/generated-artifacts/
|
||||||
|
contracts/extensions/test/generated-artifacts/
|
||||||
contracts/exchange-forwarder/generated-artifacts/
|
contracts/exchange-forwarder/generated-artifacts/
|
||||||
|
contracts/exchange-forwarder/test/generated-artifacts/
|
||||||
contracts/dev-utils/generated-artifacts/
|
contracts/dev-utils/generated-artifacts/
|
||||||
|
contracts/dev-utils/test/generated-artifacts/
|
||||||
packages/sol-tracing-utils/test/fixtures/artifacts/
|
packages/sol-tracing-utils/test/fixtures/artifacts/
|
||||||
python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/
|
python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/
|
||||||
|
|
||||||
# generated truffle contract artifacts/
|
# generated truffle contract artifacts/
|
||||||
|
contracts/erc20-bridge-sampler/build/
|
||||||
contracts/staking/build/
|
contracts/staking/build/
|
||||||
contracts/coordinator/build/
|
contracts/coordinator/build/
|
||||||
contracts/exchange/build/
|
contracts/exchange/build/
|
||||||
@@ -116,20 +130,36 @@ contracts/dev-utils/build/
|
|||||||
|
|
||||||
# generated contract wrappers
|
# generated contract wrappers
|
||||||
packages/python-contract-wrappers/generated/
|
packages/python-contract-wrappers/generated/
|
||||||
|
contracts/erc20-bridge-sampler/generated-wrappers/
|
||||||
|
contracts/erc20-bridge-sampler/test/generated-wrappers/
|
||||||
contracts/integrations/generated-wrappers/
|
contracts/integrations/generated-wrappers/
|
||||||
|
contracts/integrations/test/generated-wrappers/
|
||||||
contracts/staking/generated-wrappers/
|
contracts/staking/generated-wrappers/
|
||||||
|
contracts/staking/test/generated-wrappers/
|
||||||
contracts/coordinator/generated-wrappers/
|
contracts/coordinator/generated-wrappers/
|
||||||
|
contracts/coordinator/test/generated-wrappers/
|
||||||
contracts/exchange/generated-wrappers/
|
contracts/exchange/generated-wrappers/
|
||||||
|
contracts/exchange/test/generated-wrappers/
|
||||||
contracts/asset-proxy/generated-wrappers/
|
contracts/asset-proxy/generated-wrappers/
|
||||||
|
contracts/asset-proxy/test/generated-wrappers/
|
||||||
contracts/multisig/generated-wrappers/
|
contracts/multisig/generated-wrappers/
|
||||||
|
contracts/multisig/test/generated-wrappers/
|
||||||
contracts/utils/generated-wrappers/
|
contracts/utils/generated-wrappers/
|
||||||
|
contracts/utils/test/generated-wrappers/
|
||||||
contracts/exchange-libs/generated-wrappers/
|
contracts/exchange-libs/generated-wrappers/
|
||||||
|
contracts/exchange-libs/test/generated-wrappers/
|
||||||
contracts/erc20/generated-wrappers/
|
contracts/erc20/generated-wrappers/
|
||||||
|
contracts/erc20/test/generated-wrappers/
|
||||||
contracts/erc721/generated-wrappers/
|
contracts/erc721/generated-wrappers/
|
||||||
|
contracts/erc721/test/generated-wrappers/
|
||||||
contracts/erc1155/generated-wrappers/
|
contracts/erc1155/generated-wrappers/
|
||||||
|
contracts/erc1155/test/generated-wrappers/
|
||||||
contracts/extensions/generated-wrappers/
|
contracts/extensions/generated-wrappers/
|
||||||
|
contracts/extensions/test/generated-wrappers/
|
||||||
contracts/exchange-forwarder/generated-wrappers/
|
contracts/exchange-forwarder/generated-wrappers/
|
||||||
|
contracts/exchange-forwarder/test/generated-wrappers/
|
||||||
contracts/dev-utils/generated-wrappers/
|
contracts/dev-utils/generated-wrappers/
|
||||||
|
contracts/dev-utils/test/generated-wrappers/
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dev_utils/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dev_utils/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py
|
||||||
@@ -141,19 +171,22 @@ python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dummy_erc721_tok
|
|||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dutch_auction/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dutch_auction/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_mintable/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_mintable/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_proxy/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_proxy/__init__.py
|
||||||
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_bridge_proxy/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_proxy/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_proxy/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_proxy/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_proxy/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_token/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_token/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/eth_balance_checker/__init__.py
|
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/forwarder/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/forwarder/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_asset_proxy/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_asset_proxy/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_validator/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_validator/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_wallet/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_wallet/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/multi_asset_proxy/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/multi_asset_proxy/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_validator/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_validator/__init__.py
|
||||||
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/staking/__init__.py
|
||||||
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/staking_proxy/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/static_call_proxy/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/static_call_proxy/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/weth9/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/weth9/__init__.py
|
||||||
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_token/__init__.py
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_token/__init__.py
|
||||||
|
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_vault/__init__.py
|
||||||
|
|
||||||
# solc-bin in sol-compiler
|
# solc-bin in sol-compiler
|
||||||
packages/sol-compiler/solc_bin/
|
packages/sol-compiler/solc_bin/
|
||||||
|
@@ -1,33 +1,65 @@
|
|||||||
lib
|
lib
|
||||||
.nyc_output
|
.nyc_output
|
||||||
/contracts/integrations/generated-wrappers
|
/contracts/integrations/generated-wrappers
|
||||||
|
/contracts/integrations/test/generated-wrappers
|
||||||
/contracts/integrations/generated-artifacts
|
/contracts/integrations/generated-artifacts
|
||||||
|
/contracts/integrations/test/generated-artifacts
|
||||||
/contracts/staking/generated-wrappers
|
/contracts/staking/generated-wrappers
|
||||||
|
/contracts/staking/test/generated-wrappers
|
||||||
/contracts/staking/generated-artifacts
|
/contracts/staking/generated-artifacts
|
||||||
|
/contracts/staking/test/generated-artifacts
|
||||||
/contracts/coordinator/generated-wrappers
|
/contracts/coordinator/generated-wrappers
|
||||||
|
/contracts/coordinator/test/generated-wrappers
|
||||||
/contracts/coordinator/generated-artifacts
|
/contracts/coordinator/generated-artifacts
|
||||||
|
/contracts/coordinator/test/generated-artifacts
|
||||||
/contracts/exchange/generated-wrappers
|
/contracts/exchange/generated-wrappers
|
||||||
|
/contracts/exchange/test/generated-wrappers
|
||||||
/contracts/exchange/generated-artifacts
|
/contracts/exchange/generated-artifacts
|
||||||
|
/contracts/exchange/test/generated-artifacts
|
||||||
/contracts/asset-proxy/generated-wrappers
|
/contracts/asset-proxy/generated-wrappers
|
||||||
|
/contracts/asset-proxy/test/generated-wrappers
|
||||||
/contracts/asset-proxy/generated-artifacts
|
/contracts/asset-proxy/generated-artifacts
|
||||||
|
/contracts/asset-proxy/test/generated-artifacts
|
||||||
/contracts/multisig/generated-wrappers
|
/contracts/multisig/generated-wrappers
|
||||||
|
/contracts/multisig/test/generated-wrappers
|
||||||
/contracts/multisig/generated-artifacts
|
/contracts/multisig/generated-artifacts
|
||||||
|
/contracts/multisig/test/generated-artifacts
|
||||||
/contracts/utils/generated-wrappers
|
/contracts/utils/generated-wrappers
|
||||||
|
/contracts/utils/test/generated-wrappers
|
||||||
/contracts/utils/generated-artifacts
|
/contracts/utils/generated-artifacts
|
||||||
|
/contracts/utils/test/generated-artifacts
|
||||||
/contracts/exchange-libs/generated-wrappers
|
/contracts/exchange-libs/generated-wrappers
|
||||||
|
/contracts/exchange-libs/test/generated-wrappers
|
||||||
/contracts/exchange-libs/generated-artifacts
|
/contracts/exchange-libs/generated-artifacts
|
||||||
|
/contracts/exchange-libs/test/generated-artifacts
|
||||||
/contracts/erc20/generated-wrappers
|
/contracts/erc20/generated-wrappers
|
||||||
|
/contracts/erc20/test/generated-wrappers
|
||||||
/contracts/erc20/generated-artifacts
|
/contracts/erc20/generated-artifacts
|
||||||
|
/contracts/erc20/test/generated-artifacts
|
||||||
|
/contracts/erc20-bridge-sampler/generated-wrappers
|
||||||
|
/contracts/erc20-bridge-sampler/test/generated-wrappers
|
||||||
|
/contracts/erc20-bridge-sampler/generated-artifacts
|
||||||
|
/contracts/erc20-bridge-sampler/test/generated-artifacts
|
||||||
/contracts/erc721/generated-wrappers
|
/contracts/erc721/generated-wrappers
|
||||||
|
/contracts/erc721/test/generated-wrappers
|
||||||
/contracts/erc721/generated-artifacts
|
/contracts/erc721/generated-artifacts
|
||||||
|
/contracts/erc721/test/generated-artifacts
|
||||||
/contracts/erc1155/generated-wrappers
|
/contracts/erc1155/generated-wrappers
|
||||||
|
/contracts/erc1155/test/generated-wrappers
|
||||||
/contracts/erc1155/generated-artifacts
|
/contracts/erc1155/generated-artifacts
|
||||||
|
/contracts/erc1155/test/generated-artifacts
|
||||||
/contracts/extensions/generated-wrappers
|
/contracts/extensions/generated-wrappers
|
||||||
|
/contracts/extensions/test/generated-wrappers
|
||||||
/contracts/extensions/generated-artifacts
|
/contracts/extensions/generated-artifacts
|
||||||
|
/contracts/extensions/test/generated-artifacts
|
||||||
/contracts/exchange-forwarder/generated-wrappers
|
/contracts/exchange-forwarder/generated-wrappers
|
||||||
|
/contracts/exchange-forwarder/test/generated-wrappers
|
||||||
/contracts/exchange-forwarder/generated-artifacts
|
/contracts/exchange-forwarder/generated-artifacts
|
||||||
|
/contracts/exchange-forwarder/test/generated-artifacts
|
||||||
/contracts/dev-utils/generated-wrappers
|
/contracts/dev-utils/generated-wrappers
|
||||||
|
/contracts/dev-utils/test/generated-wrappers
|
||||||
/contracts/dev-utils/generated-artifacts
|
/contracts/dev-utils/generated-artifacts
|
||||||
|
/contracts/dev-utils/test/generated-artifacts
|
||||||
/contracts/staking/build/
|
/contracts/staking/build/
|
||||||
/contracts/coordinator/build/
|
/contracts/coordinator/build/
|
||||||
/contracts/exchange/build/
|
/contracts/exchange/build/
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"tabWidth": 4,
|
|
||||||
"printWidth": 120,
|
"printWidth": 120,
|
||||||
"trailingComma": all,
|
"tabWidth": 4,
|
||||||
"singleQuote": true
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
}
|
}
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
# https://git-scm.com/docs/gitignore#_pattern_format
|
# https://git-scm.com/docs/gitignore#_pattern_format
|
||||||
|
|
||||||
# Website
|
# Website
|
||||||
packages/asset-buyer/ @BMillman19 @fragosti @steveklebanoff
|
packages/asset-swapper/ @BMillman19 @fragosti @dave4506
|
||||||
packages/instant/ @BMillman19 @fragosti @steveklebanoff
|
packages/instant/ @BMillman19 @fragosti @dave4506
|
||||||
|
|
||||||
# Dev tools & setup
|
# Dev tools & setup
|
||||||
.circleci/ @LogvinovLeon
|
.circleci/ @LogvinovLeon
|
||||||
|
11
README.md
11
README.md
@@ -61,11 +61,9 @@ These packages are all under development. See [/contracts/README.md](/contracts/
|
|||||||
| [`@0x/order-utils`](/packages/order-utils) | [](https://www.npmjs.com/package/@0x/order-utils) | A set of utilities for generating, parsing, signing and validating 0x orders |
|
| [`@0x/order-utils`](/packages/order-utils) | [](https://www.npmjs.com/package/@0x/order-utils) | A set of utilities for generating, parsing, signing and validating 0x orders |
|
||||||
| [`@0x/json-schemas`](/packages/json-schemas) | [](https://www.npmjs.com/package/@0x/json-schemas) | 0x-related JSON schemas | |
|
| [`@0x/json-schemas`](/packages/json-schemas) | [](https://www.npmjs.com/package/@0x/json-schemas) | 0x-related JSON schemas | |
|
||||||
| [`@0x/migrations`](/packages/migrations) | [](https://www.npmjs.com/package/@0x/migrations) | Migration tool for deploying 0x smart contracts on private testnets |
|
| [`@0x/migrations`](/packages/migrations) | [](https://www.npmjs.com/package/@0x/migrations) | Migration tool for deploying 0x smart contracts on private testnets |
|
||||||
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts |
|
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts | |
|
||||||
| [`@0x/abi-gen-wrappers`](/packages/abi-gen-wrappers) | [](https://www.npmjs.com/package/@0x/abi-gen-wrappers) | Low-level 0x smart contract wrappers generated using `@0x/abi-gen` |
|
|
||||||
| [`@0x/sra-spec`](/packages/sra-spec) | [](https://www.npmjs.com/package/@0x/sra-spec) | OpenAPI specification for the Standard Relayer API |
|
| [`@0x/sra-spec`](/packages/sra-spec) | [](https://www.npmjs.com/package/@0x/sra-spec) | OpenAPI specification for the Standard Relayer API |
|
||||||
| [`@0x/connect`](/packages/connect) | [](https://www.npmjs.com/package/@0x/connect) | An HTTP/WS client for interacting with the Standard Relayer API |
|
| [`@0x/connect`](/packages/connect) | [](https://www.npmjs.com/package/@0x/connect) | An HTTP/WS client for interacting with the Standard Relayer API |
|
||||||
| [`@0x/asset-buyer`](/packages/asset-buyer) | [](https://www.npmjs.com/package/@0x/asset-buyer) | Convenience package for discovering and buying assets with Ether |
|
|
||||||
| [`@0x/asset-swapper`](/packages/asset-swapper) | [](https://www.npmjs.com/package/@0x/asset-swapper) | Convenience package for discovering and performing swaps for any ERC20 Assets |
|
| [`@0x/asset-swapper`](/packages/asset-swapper) | [](https://www.npmjs.com/package/@0x/asset-swapper) | Convenience package for discovering and performing swaps for any ERC20 Assets |
|
||||||
|
|
||||||
#### Ethereum tooling
|
#### Ethereum tooling
|
||||||
@@ -96,10 +94,9 @@ These packages are all under development. See [/contracts/README.md](/contracts/
|
|||||||
|
|
||||||
#### Private Packages
|
#### Private Packages
|
||||||
|
|
||||||
| Package | Description |
|
| Package | Description |
|
||||||
| -------------------------------------------------- | -------------------------------------------------------------------------------- |
|
| ---------------------------------- | -------------------------------------------------------------------------------- |
|
||||||
| [`@0x/instant`](/packages/instant) | A free and flexible way to offer simple crypto purchasing in any app or website. |
|
| [`@0x/instant`](/packages/instant) | A free and flexible way to offer simple crypto purchasing in any app or website. |
|
||||||
| [`@0x/testnet-faucets`](/packages/testnet-faucets) | A faucet micro-service that dispenses test ERC20 tokens or Ether |
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@@ -13,4 +13,4 @@
|
|||||||
|
|
||||||
#### Development
|
#### Development
|
||||||
|
|
||||||
Building solidity files will update the contract artifact in `{package-name}/generated-artifacts/{contract}.json`, but does not automatically update the `abi-gen-wrappers` package, which are generated from the artifact JSON. To ensure consistency, clean and rebuild `abi-gen-wrappers` after any changes to the artifact JSON.
|
Building solidity files will update the contract artifact in `{package-name}/generated-artifacts/{contract}.json`, but does not automatically update the `contract-artifacts` or `contract-wrappers` packages, which are generated from the artifact JSON. See `contract-artifacts/README.md` for instructions on updating these packages.
|
||||||
|
10
contracts/asset-proxy/.npmignore
Normal file
10
contracts/asset-proxy/.npmignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Blacklist all files
|
||||||
|
.*
|
||||||
|
*
|
||||||
|
# Whitelist lib
|
||||||
|
!lib/**/*
|
||||||
|
# Whitelist Solidity contracts
|
||||||
|
!contracts/src/**/*
|
||||||
|
# Blacklist tests in lib
|
||||||
|
/lib/test/*
|
||||||
|
# Package specific ignore
|
@@ -1,4 +1,92 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1575931811,
|
||||||
|
"version": "3.0.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "3.0.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Implement `KyberBridge`.",
|
||||||
|
"pr": 2352
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
|
||||||
|
"pr": 2330
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract",
|
||||||
|
"pr": 2034
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Disallow the zero address from being made an authorized address in MixinAuthorizable, and created an archive directory that includes an old version of Ownable",
|
||||||
|
"pr": 2019
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Remove `LibAssetProxyIds` contract",
|
||||||
|
"pr": 2055
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Compile and export all contracts, artifacts, and wrappers by default",
|
||||||
|
"pr": 2055
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Remove unused dependency on IAuthorizable in IAssetProxy",
|
||||||
|
"pr": 1910
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `ERC20BridgeProxy`",
|
||||||
|
"pr": 2220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `Eth2DaiBridge`",
|
||||||
|
"pr": 2221
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `UniswapBridge`",
|
||||||
|
"pr": 2233
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Replaced `SafeMath` with `LibSafeMath`",
|
||||||
|
"pr": 2254
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575296764
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.3.0-beta.4",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Implement `KyberBridge`.",
|
||||||
|
"pr": 2352
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575290197
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.3.0-beta.3",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1574238768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.3.0-beta.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
|
||||||
|
"pr": 2330
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1574030254
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "2.3.0-beta.1",
|
"version": "2.3.0-beta.1",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@@ -5,6 +5,36 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v3.0.1 - _December 9, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.0.0 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Implement `KyberBridge`. (#2352)
|
||||||
|
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
|
||||||
|
* ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract (#2034)
|
||||||
|
* Disallow the zero address from being made an authorized address in MixinAuthorizable, and created an archive directory that includes an old version of Ownable (#2019)
|
||||||
|
* Remove `LibAssetProxyIds` contract (#2055)
|
||||||
|
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
|
||||||
|
* Remove unused dependency on IAuthorizable in IAssetProxy (#1910)
|
||||||
|
* Add `ERC20BridgeProxy` (#2220)
|
||||||
|
* Add `Eth2DaiBridge` (#2221)
|
||||||
|
* Add `UniswapBridge` (#2233)
|
||||||
|
* Replaced `SafeMath` with `LibSafeMath` (#2254)
|
||||||
|
|
||||||
|
## v2.3.0-beta.4 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Implement `KyberBridge`. (#2352)
|
||||||
|
|
||||||
|
## v2.3.0-beta.3 - _November 20, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.3.0-beta.2 - _November 17, 2019_
|
||||||
|
|
||||||
|
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
|
||||||
|
|
||||||
## v2.3.0-beta.1 - _November 7, 2019_
|
## v2.3.0-beta.1 - _November 7, 2019_
|
||||||
|
|
||||||
* ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract (#2034)
|
* ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract (#2034)
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"artifactsDir": "./generated-artifacts",
|
"artifactsDir": "./test/generated-artifacts",
|
||||||
"contractsDir": "./contracts",
|
"contractsDir": "./contracts",
|
||||||
"useDockerisedSolc": false,
|
"useDockerisedSolc": false,
|
||||||
"isOfflineMode": false,
|
"isOfflineMode": false,
|
||||||
|
75
contracts/asset-proxy/contracts/src/bridges/ChaiBridge.sol
Normal file
75
contracts/asset-proxy/contracts/src/bridges/ChaiBridge.sol
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2019 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "../interfaces/IERC20Bridge.sol";
|
||||||
|
import "../interfaces/IChai.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||||
|
|
||||||
|
|
||||||
|
// solhint-disable space-after-comma
|
||||||
|
contract ChaiBridge is
|
||||||
|
IERC20Bridge,
|
||||||
|
DeploymentConstants
|
||||||
|
{
|
||||||
|
/// @dev Withdraws `amount` of `from` address's Dai from the Chai contract.
|
||||||
|
/// Transfers `amount` of Dai to `to` address.
|
||||||
|
/// @param from Address to transfer asset from.
|
||||||
|
/// @param to Address to transfer asset to.
|
||||||
|
/// @param amount Amount of asset to transfer.
|
||||||
|
/// @return success The magic bytes `0x37708e9b` if successful.
|
||||||
|
function bridgeTransferFrom(
|
||||||
|
address /* tokenAddress */,
|
||||||
|
address from,
|
||||||
|
address to,
|
||||||
|
uint256 amount,
|
||||||
|
bytes calldata /* bridgeData */
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (bytes4 success)
|
||||||
|
{
|
||||||
|
// Ensure that only the `ERC20BridgeProxy` can call this function.
|
||||||
|
require(
|
||||||
|
msg.sender == _getERC20BridgeProxyAddress(),
|
||||||
|
"ChaiBridge/ONLY_CALLABLE_BY_ERC20_BRIDGE_PROXY"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Withdraw `from` address's Dai.
|
||||||
|
// NOTE: This contract must be approved to spend Chai on behalf of `from`.
|
||||||
|
bytes memory drawCalldata = abi.encodeWithSelector(
|
||||||
|
IChai(address(0)).draw.selector,
|
||||||
|
from,
|
||||||
|
amount
|
||||||
|
);
|
||||||
|
|
||||||
|
(bool success,) = _getChaiAddress().call(drawCalldata);
|
||||||
|
require(
|
||||||
|
success,
|
||||||
|
"ChaiBridge/DRAW_DAI_FAILED"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Transfer Dai to `to`
|
||||||
|
// This will never fail if the `draw` call was successful
|
||||||
|
IERC20Token(_getDaiAddress()).transfer(to, amount);
|
||||||
|
|
||||||
|
return BRIDGE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
|
|||||||
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||||
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||||
import "../interfaces/IERC20Bridge.sol";
|
import "../interfaces/IERC20Bridge.sol";
|
||||||
import "../interfaces/IEth2Dai.sol";
|
import "../interfaces/IEth2Dai.sol";
|
||||||
|
|
||||||
@@ -29,11 +30,9 @@ import "../interfaces/IEth2Dai.sol";
|
|||||||
// solhint-disable space-after-comma
|
// solhint-disable space-after-comma
|
||||||
contract Eth2DaiBridge is
|
contract Eth2DaiBridge is
|
||||||
IERC20Bridge,
|
IERC20Bridge,
|
||||||
IWallet
|
IWallet,
|
||||||
|
DeploymentConstants
|
||||||
{
|
{
|
||||||
/* Mainnet addresses */
|
|
||||||
address constant public ETH2DAI_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
|
|
||||||
|
|
||||||
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
|
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
|
||||||
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
|
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
|
||||||
/// (DAI or WETH) to the Eth2Dai contract, then transfers the bought
|
/// (DAI or WETH) to the Eth2Dai contract, then transfers the bought
|
||||||
@@ -56,13 +55,13 @@ contract Eth2DaiBridge is
|
|||||||
// Decode the bridge data to get the `fromTokenAddress`.
|
// Decode the bridge data to get the `fromTokenAddress`.
|
||||||
(address fromTokenAddress) = abi.decode(bridgeData, (address));
|
(address fromTokenAddress) = abi.decode(bridgeData, (address));
|
||||||
|
|
||||||
IEth2Dai exchange = _getEth2DaiContract();
|
IEth2Dai exchange = IEth2Dai(_getEth2DaiAddress());
|
||||||
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
|
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
|
||||||
LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1));
|
LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1));
|
||||||
|
|
||||||
// Try to sell all of this contract's `fromTokenAddress` token balance.
|
// Try to sell all of this contract's `fromTokenAddress` token balance.
|
||||||
uint256 boughtAmount = _getEth2DaiContract().sellAllAmount(
|
uint256 boughtAmount = exchange.sellAllAmount(
|
||||||
address(fromTokenAddress),
|
fromTokenAddress,
|
||||||
IERC20Token(fromTokenAddress).balanceOf(address(this)),
|
IERC20Token(fromTokenAddress).balanceOf(address(this)),
|
||||||
toTokenAddress,
|
toTokenAddress,
|
||||||
amount
|
amount
|
||||||
@@ -85,14 +84,4 @@ contract Eth2DaiBridge is
|
|||||||
{
|
{
|
||||||
return LEGACY_WALLET_MAGIC_VALUE;
|
return LEGACY_WALLET_MAGIC_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Overridable way to get the eth2dai contract.
|
|
||||||
/// @return exchange The Eth2Dai exchange contract.
|
|
||||||
function _getEth2DaiContract()
|
|
||||||
internal
|
|
||||||
view
|
|
||||||
returns (IEth2Dai exchange)
|
|
||||||
{
|
|
||||||
return IEth2Dai(ETH2DAI_ADDRESS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
146
contracts/asset-proxy/contracts/src/bridges/KyberBridge.sol
Normal file
146
contracts/asset-proxy/contracts/src/bridges/KyberBridge.sol
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2019 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||||
|
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||||
|
import "../interfaces/IERC20Bridge.sol";
|
||||||
|
import "../interfaces/IKyberNetworkProxy.sol";
|
||||||
|
|
||||||
|
|
||||||
|
// solhint-disable space-after-comma
|
||||||
|
contract KyberBridge is
|
||||||
|
IERC20Bridge,
|
||||||
|
IWallet,
|
||||||
|
DeploymentConstants
|
||||||
|
{
|
||||||
|
// @dev Structure used internally to get around stack limits.
|
||||||
|
struct TradeState {
|
||||||
|
IKyberNetworkProxy kyber;
|
||||||
|
IEtherToken weth;
|
||||||
|
address fromTokenAddress;
|
||||||
|
uint256 fromTokenBalance;
|
||||||
|
uint256 payableAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Kyber ETH pseudo-address.
|
||||||
|
address constant public KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||||
|
/// @dev `bridgeTransferFrom()` failure result.
|
||||||
|
bytes4 constant private BRIDGE_FAILED = 0x0;
|
||||||
|
/// @dev Precision of Kyber rates.
|
||||||
|
uint256 constant private KYBER_RATE_BASE = 10 ** 18;
|
||||||
|
|
||||||
|
// solhint-disable no-empty-blocks
|
||||||
|
/// @dev Payable fallback to receive ETH from Kyber.
|
||||||
|
function ()
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// @dev Callback for `IKyberBridge`. Tries to buy `amount` of
|
||||||
|
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
|
||||||
|
/// to the `KyberNetworkProxy` contract, then transfers the bought
|
||||||
|
/// tokens to `to`.
|
||||||
|
/// @param toTokenAddress The token to give to `to`.
|
||||||
|
/// @param to The recipient of the bought tokens.
|
||||||
|
/// @param amount Minimum amount of `toTokenAddress` tokens to buy.
|
||||||
|
/// @param bridgeData The abi-encoeded "from" token address.
|
||||||
|
/// @return success The magic bytes if successful.
|
||||||
|
function bridgeTransferFrom(
|
||||||
|
address toTokenAddress,
|
||||||
|
address /* from */,
|
||||||
|
address to,
|
||||||
|
uint256 amount,
|
||||||
|
bytes calldata bridgeData
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (bytes4 success)
|
||||||
|
{
|
||||||
|
TradeState memory state;
|
||||||
|
state.kyber = IKyberNetworkProxy(_getKyberNetworkProxyAddress());
|
||||||
|
state.weth = IEtherToken(_getWethAddress());
|
||||||
|
// Decode the bridge data to get the `fromTokenAddress`.
|
||||||
|
(state.fromTokenAddress) = abi.decode(bridgeData, (address));
|
||||||
|
state.fromTokenBalance = IERC20Token(state.fromTokenAddress).balanceOf(address(this));
|
||||||
|
if (state.fromTokenBalance == 0) {
|
||||||
|
// Return failure if no input tokens.
|
||||||
|
return BRIDGE_FAILED;
|
||||||
|
}
|
||||||
|
if (state.fromTokenAddress == toTokenAddress) {
|
||||||
|
// Just transfer the tokens if they're the same.
|
||||||
|
LibERC20Token.transfer(state.fromTokenAddress, to, state.fromTokenBalance);
|
||||||
|
return BRIDGE_SUCCESS;
|
||||||
|
} else if (state.fromTokenAddress != address(state.weth)) {
|
||||||
|
// If the input token is not WETH, grant an allowance to the exchange
|
||||||
|
// to spend them.
|
||||||
|
LibERC20Token.approve(state.fromTokenAddress, address(state.kyber), uint256(-1));
|
||||||
|
} else {
|
||||||
|
// If the input token is WETH, unwrap it and attach it to the call.
|
||||||
|
state.fromTokenAddress = KYBER_ETH_ADDRESS;
|
||||||
|
state.payableAmount = state.fromTokenBalance;
|
||||||
|
state.weth.withdraw(state.fromTokenBalance);
|
||||||
|
}
|
||||||
|
bool isToTokenWeth = toTokenAddress == address(state.weth);
|
||||||
|
|
||||||
|
// Try to sell all of this contract's input token balance through
|
||||||
|
// `KyberNetworkProxy.trade()`.
|
||||||
|
uint256 boughtAmount = state.kyber.trade.value(state.payableAmount)(
|
||||||
|
// Input token.
|
||||||
|
state.fromTokenAddress,
|
||||||
|
// Sell amount.
|
||||||
|
state.fromTokenBalance,
|
||||||
|
// Output token.
|
||||||
|
isToTokenWeth ? KYBER_ETH_ADDRESS : toTokenAddress,
|
||||||
|
// Transfer to this contract if converting to ETH, otherwise
|
||||||
|
// transfer directly to the recipient.
|
||||||
|
isToTokenWeth ? address(uint160(address(this))) : address(uint160(to)),
|
||||||
|
// Buy as much as possible.
|
||||||
|
uint256(-1),
|
||||||
|
// Compute the minimum conversion rate, which is expressed in units with
|
||||||
|
// 18 decimal places.
|
||||||
|
(KYBER_RATE_BASE * amount) / state.fromTokenBalance,
|
||||||
|
// No affiliate address.
|
||||||
|
address(0)
|
||||||
|
);
|
||||||
|
// Wrap ETH output and transfer to recipient.
|
||||||
|
if (isToTokenWeth) {
|
||||||
|
state.weth.deposit.value(boughtAmount)();
|
||||||
|
state.weth.transfer(to, boughtAmount);
|
||||||
|
}
|
||||||
|
return BRIDGE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker
|
||||||
|
/// and sign for itself in orders. Always succeeds.
|
||||||
|
/// @return magicValue Magic success bytes, always.
|
||||||
|
function isValidSignature(
|
||||||
|
bytes32,
|
||||||
|
bytes calldata
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (bytes4 magicValue)
|
||||||
|
{
|
||||||
|
return LEGACY_WALLET_MAGIC_VALUE;
|
||||||
|
}
|
||||||
|
}
|
@@ -23,6 +23,7 @@ import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
|||||||
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
|
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
|
||||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||||
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||||
import "../interfaces/IUniswapExchangeFactory.sol";
|
import "../interfaces/IUniswapExchangeFactory.sol";
|
||||||
import "../interfaces/IUniswapExchange.sol";
|
import "../interfaces/IUniswapExchange.sol";
|
||||||
import "../interfaces/IERC20Bridge.sol";
|
import "../interfaces/IERC20Bridge.sol";
|
||||||
@@ -32,12 +33,9 @@ import "../interfaces/IERC20Bridge.sol";
|
|||||||
// solhint-disable not-rely-on-time
|
// solhint-disable not-rely-on-time
|
||||||
contract UniswapBridge is
|
contract UniswapBridge is
|
||||||
IERC20Bridge,
|
IERC20Bridge,
|
||||||
IWallet
|
IWallet,
|
||||||
|
DeploymentConstants
|
||||||
{
|
{
|
||||||
/* Mainnet addresses */
|
|
||||||
address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
|
||||||
address constant private WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
|
||||||
|
|
||||||
// Struct to hold `bridgeTransferFrom()` local variables in memory and to avoid
|
// Struct to hold `bridgeTransferFrom()` local variables in memory and to avoid
|
||||||
// stack overflows.
|
// stack overflows.
|
||||||
struct WithdrawToState {
|
struct WithdrawToState {
|
||||||
@@ -90,7 +88,7 @@ contract UniswapBridge is
|
|||||||
// Get our balance of `fromTokenAddress` token.
|
// Get our balance of `fromTokenAddress` token.
|
||||||
state.fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this));
|
state.fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this));
|
||||||
// Get the weth contract.
|
// Get the weth contract.
|
||||||
state.weth = getWethContract();
|
state.weth = IEtherToken(_getWethAddress());
|
||||||
|
|
||||||
// Convert from WETH to a token.
|
// Convert from WETH to a token.
|
||||||
if (fromTokenAddress == address(state.weth)) {
|
if (fromTokenAddress == address(state.weth)) {
|
||||||
@@ -163,26 +161,6 @@ contract UniswapBridge is
|
|||||||
return LEGACY_WALLET_MAGIC_VALUE;
|
return LEGACY_WALLET_MAGIC_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Overridable way to get the weth contract.
|
|
||||||
/// @return token The WETH contract.
|
|
||||||
function getWethContract()
|
|
||||||
public
|
|
||||||
view
|
|
||||||
returns (IEtherToken token)
|
|
||||||
{
|
|
||||||
return IEtherToken(WETH_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @dev Overridable way to get the uniswap exchange factory contract.
|
|
||||||
/// @return factory The exchange factory contract.
|
|
||||||
function getUniswapExchangeFactoryContract()
|
|
||||||
public
|
|
||||||
view
|
|
||||||
returns (IUniswapExchangeFactory factory)
|
|
||||||
{
|
|
||||||
return IUniswapExchangeFactory(UNISWAP_EXCHANGE_FACTORY_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @dev Grants an unlimited allowance to the exchange for its token
|
/// @dev Grants an unlimited allowance to the exchange for its token
|
||||||
/// on behalf of this contract.
|
/// on behalf of this contract.
|
||||||
/// @param exchange The Uniswap token exchange.
|
/// @param exchange The Uniswap token exchange.
|
||||||
@@ -209,10 +187,13 @@ contract UniswapBridge is
|
|||||||
{
|
{
|
||||||
address exchangeTokenAddress = fromTokenAddress;
|
address exchangeTokenAddress = fromTokenAddress;
|
||||||
// Whichever isn't WETH is the exchange token.
|
// Whichever isn't WETH is the exchange token.
|
||||||
if (fromTokenAddress == address(getWethContract())) {
|
if (fromTokenAddress == _getWethAddress()) {
|
||||||
exchangeTokenAddress = toTokenAddress;
|
exchangeTokenAddress = toTokenAddress;
|
||||||
}
|
}
|
||||||
exchange = getUniswapExchangeFactoryContract().getExchange(exchangeTokenAddress);
|
exchange = IUniswapExchange(
|
||||||
|
IUniswapExchangeFactory(_getUniswapExchangeFactoryAddress())
|
||||||
|
.getExchange(exchangeTokenAddress)
|
||||||
|
);
|
||||||
require(address(exchange) != address(0), "NO_UNISWAP_EXCHANGE_FOR_TOKEN");
|
require(address(exchange) != address(0), "NO_UNISWAP_EXCHANGE_FOR_TOKEN");
|
||||||
return exchange;
|
return exchange;
|
||||||
}
|
}
|
||||||
|
33
contracts/asset-proxy/contracts/src/interfaces/IChai.sol
Normal file
33
contracts/asset-proxy/contracts/src/interfaces/IChai.sol
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2019 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
|
||||||
|
|
||||||
|
// The actual Chai contract can be found here: https://github.com/dapphub/chai
|
||||||
|
contract IChai {
|
||||||
|
|
||||||
|
/// @dev Withdraws Dai owned by `src`
|
||||||
|
/// @param src Address that owns Dai.
|
||||||
|
/// @param wad Amount of Dai to withdraw.
|
||||||
|
function draw(
|
||||||
|
address src,
|
||||||
|
uint256 wad
|
||||||
|
)
|
||||||
|
external;
|
||||||
|
}
|
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2019 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
|
||||||
|
|
||||||
|
interface IKyberNetworkProxy {
|
||||||
|
|
||||||
|
/// @dev Sells `sellTokenAddress` tokens for `buyTokenAddress` tokens.
|
||||||
|
/// @param sellTokenAddress Token to sell.
|
||||||
|
/// @param sellAmount Amount of tokens to sell.
|
||||||
|
/// @param buyTokenAddress Token to buy.
|
||||||
|
/// @param recipientAddress Address to send bought tokens to.
|
||||||
|
/// @param maxBuyTokenAmount A limit on the amount of tokens to buy.
|
||||||
|
/// @param minConversionRate The minimal conversion rate. If actual rate
|
||||||
|
/// is lower, trade is canceled.
|
||||||
|
/// @param walletId The wallet ID to send part of the fees
|
||||||
|
/// @return boughtAmount Amount of tokens bought.
|
||||||
|
function trade(
|
||||||
|
address sellTokenAddress,
|
||||||
|
uint256 sellAmount,
|
||||||
|
address buyTokenAddress,
|
||||||
|
address payable recipientAddress,
|
||||||
|
uint256 maxBuyTokenAmount,
|
||||||
|
uint256 minConversionRate,
|
||||||
|
address walletId
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns(uint256 boughtAmount);
|
||||||
|
}
|
@@ -67,11 +67,4 @@ interface IUniswapExchange {
|
|||||||
)
|
)
|
||||||
external
|
external
|
||||||
returns (uint256 tokensBought);
|
returns (uint256 tokensBought);
|
||||||
|
|
||||||
/// @dev Retrieves the token that is associated with this exchange.
|
|
||||||
/// @return tokenAddress The token address.
|
|
||||||
function toTokenAddress()
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (address tokenAddress);
|
|
||||||
}
|
}
|
||||||
|
@@ -28,5 +28,5 @@ interface IUniswapExchangeFactory {
|
|||||||
function getExchange(address tokenAddress)
|
function getExchange(address tokenAddress)
|
||||||
external
|
external
|
||||||
view
|
view
|
||||||
returns (IUniswapExchange);
|
returns (address);
|
||||||
}
|
}
|
||||||
|
80
contracts/asset-proxy/contracts/test/TestChaiBridge.sol
Normal file
80
contracts/asset-proxy/contracts/test/TestChaiBridge.sol
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2019 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "../src/bridges/ChaiBridge.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/ERC20Token.sol";
|
||||||
|
|
||||||
|
|
||||||
|
contract TestChaiDai is
|
||||||
|
ERC20Token
|
||||||
|
{
|
||||||
|
address private constant ALWAYS_REVERT_ADDRESS = address(1);
|
||||||
|
|
||||||
|
function draw(
|
||||||
|
address from,
|
||||||
|
uint256 amount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
{
|
||||||
|
if (from == ALWAYS_REVERT_ADDRESS) {
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
balances[msg.sender] += amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
contract TestChaiBridge is
|
||||||
|
ChaiBridge
|
||||||
|
{
|
||||||
|
address public testChaiDai;
|
||||||
|
address private constant ALWAYS_REVERT_ADDRESS = address(1);
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
public
|
||||||
|
{
|
||||||
|
testChaiDai = address(new TestChaiDai());
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getDaiAddress()
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (address)
|
||||||
|
{
|
||||||
|
return testChaiDai;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getChaiAddress()
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (address)
|
||||||
|
{
|
||||||
|
return testChaiDai;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getERC20BridgeProxyAddress()
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (address)
|
||||||
|
{
|
||||||
|
return msg.sender == ALWAYS_REVERT_ADDRESS ? address(0) : msg.sender;
|
||||||
|
}
|
||||||
|
}
|
@@ -192,11 +192,11 @@ contract TestEth2DaiBridge is
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @dev This contract will double as the Eth2Dai contract.
|
// @dev This contract will double as the Eth2Dai contract.
|
||||||
function _getEth2DaiContract()
|
function _getEth2DaiAddress()
|
||||||
internal
|
internal
|
||||||
view
|
view
|
||||||
returns (IEth2Dai)
|
returns (address)
|
||||||
{
|
{
|
||||||
return IEth2Dai(address(this));
|
return address(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
322
contracts/asset-proxy/contracts/test/TestKyberBridge.sol
Normal file
322
contracts/asset-proxy/contracts/test/TestKyberBridge.sol
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2019 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||||
|
import "../src/bridges/KyberBridge.sol";
|
||||||
|
import "../src/interfaces/IKyberNetworkProxy.sol";
|
||||||
|
|
||||||
|
|
||||||
|
// solhint-disable no-simple-event-func-name
|
||||||
|
interface ITestContract {
|
||||||
|
|
||||||
|
function wethWithdraw(
|
||||||
|
address payable ownerAddress,
|
||||||
|
uint256 amount
|
||||||
|
)
|
||||||
|
external;
|
||||||
|
|
||||||
|
function wethDeposit(
|
||||||
|
address ownerAddress
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable;
|
||||||
|
|
||||||
|
function tokenTransfer(
|
||||||
|
address ownerAddress,
|
||||||
|
address recipientAddress,
|
||||||
|
uint256 amount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (bool success);
|
||||||
|
|
||||||
|
function tokenApprove(
|
||||||
|
address ownerAddress,
|
||||||
|
address spenderAddress,
|
||||||
|
uint256 allowance
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (bool success);
|
||||||
|
|
||||||
|
function tokenBalanceOf(
|
||||||
|
address ownerAddress
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256 balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev A minimalist ERC20/WETH token.
|
||||||
|
contract TestToken {
|
||||||
|
|
||||||
|
ITestContract private _testContract;
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
_testContract = ITestContract(msg.sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
function approve(address spender, uint256 allowance)
|
||||||
|
external
|
||||||
|
returns (bool)
|
||||||
|
{
|
||||||
|
return _testContract.tokenApprove(
|
||||||
|
msg.sender,
|
||||||
|
spender,
|
||||||
|
allowance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transfer(address recipient, uint256 amount)
|
||||||
|
external
|
||||||
|
returns (bool)
|
||||||
|
{
|
||||||
|
return _testContract.tokenTransfer(
|
||||||
|
msg.sender,
|
||||||
|
recipient,
|
||||||
|
amount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function withdraw(uint256 amount)
|
||||||
|
external
|
||||||
|
{
|
||||||
|
return _testContract.wethWithdraw(msg.sender, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deposit()
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
{
|
||||||
|
return _testContract.wethDeposit.value(msg.value)(msg.sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
function balanceOf(address owner)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return _testContract.tokenBalanceOf(owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev KyberBridge overridden to mock tokens and implement IKyberBridge.
|
||||||
|
contract TestKyberBridge is
|
||||||
|
KyberBridge,
|
||||||
|
ITestContract,
|
||||||
|
IKyberNetworkProxy
|
||||||
|
{
|
||||||
|
event KyberBridgeTrade(
|
||||||
|
uint256 msgValue,
|
||||||
|
address sellTokenAddress,
|
||||||
|
uint256 sellAmount,
|
||||||
|
address buyTokenAddress,
|
||||||
|
address payable recipientAddress,
|
||||||
|
uint256 maxBuyTokenAmount,
|
||||||
|
uint256 minConversionRate,
|
||||||
|
address walletId
|
||||||
|
);
|
||||||
|
|
||||||
|
event KyberBridgeWethWithdraw(
|
||||||
|
address ownerAddress,
|
||||||
|
uint256 amount
|
||||||
|
);
|
||||||
|
|
||||||
|
event KyberBridgeWethDeposit(
|
||||||
|
uint256 msgValue,
|
||||||
|
address ownerAddress,
|
||||||
|
uint256 amount
|
||||||
|
);
|
||||||
|
|
||||||
|
event KyberBridgeTokenApprove(
|
||||||
|
address tokenAddress,
|
||||||
|
address ownerAddress,
|
||||||
|
address spenderAddress,
|
||||||
|
uint256 allowance
|
||||||
|
);
|
||||||
|
|
||||||
|
event KyberBridgeTokenTransfer(
|
||||||
|
address tokenAddress,
|
||||||
|
address ownerAddress,
|
||||||
|
address recipientAddress,
|
||||||
|
uint256 amount
|
||||||
|
);
|
||||||
|
|
||||||
|
IEtherToken public weth;
|
||||||
|
mapping (address => mapping (address => uint256)) private _tokenBalances;
|
||||||
|
uint256 private _nextFillAmount;
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
weth = IEtherToken(address(new TestToken()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Implementation of `IKyberNetworkProxy.trade()`
|
||||||
|
function trade(
|
||||||
|
address sellTokenAddress,
|
||||||
|
uint256 sellAmount,
|
||||||
|
address buyTokenAddress,
|
||||||
|
address payable recipientAddress,
|
||||||
|
uint256 maxBuyTokenAmount,
|
||||||
|
uint256 minConversionRate,
|
||||||
|
address walletId
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns(uint256 boughtAmount)
|
||||||
|
{
|
||||||
|
emit KyberBridgeTrade(
|
||||||
|
msg.value,
|
||||||
|
sellTokenAddress,
|
||||||
|
sellAmount,
|
||||||
|
buyTokenAddress,
|
||||||
|
recipientAddress,
|
||||||
|
maxBuyTokenAmount,
|
||||||
|
minConversionRate,
|
||||||
|
walletId
|
||||||
|
);
|
||||||
|
return _nextFillAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createToken()
|
||||||
|
external
|
||||||
|
returns (address tokenAddress)
|
||||||
|
{
|
||||||
|
return address(new TestToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
function setNextFillAmount(uint256 amount)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
{
|
||||||
|
if (msg.value != 0) {
|
||||||
|
require(amount == msg.value, "VALUE_AMOUNT_MISMATCH");
|
||||||
|
grantTokensTo(address(weth), address(this), msg.value);
|
||||||
|
}
|
||||||
|
_nextFillAmount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wethDeposit(
|
||||||
|
address ownerAddress
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
{
|
||||||
|
require(msg.sender == address(weth), "ONLY_WETH");
|
||||||
|
grantTokensTo(address(weth), ownerAddress, msg.value);
|
||||||
|
emit KyberBridgeWethDeposit(
|
||||||
|
msg.value,
|
||||||
|
ownerAddress,
|
||||||
|
msg.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wethWithdraw(
|
||||||
|
address payable ownerAddress,
|
||||||
|
uint256 amount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
{
|
||||||
|
require(msg.sender == address(weth), "ONLY_WETH");
|
||||||
|
_tokenBalances[address(weth)][ownerAddress] -= amount;
|
||||||
|
ownerAddress.transfer(amount);
|
||||||
|
emit KyberBridgeWethWithdraw(
|
||||||
|
ownerAddress,
|
||||||
|
amount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tokenApprove(
|
||||||
|
address ownerAddress,
|
||||||
|
address spenderAddress,
|
||||||
|
uint256 allowance
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (bool success)
|
||||||
|
{
|
||||||
|
emit KyberBridgeTokenApprove(
|
||||||
|
msg.sender,
|
||||||
|
ownerAddress,
|
||||||
|
spenderAddress,
|
||||||
|
allowance
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tokenTransfer(
|
||||||
|
address ownerAddress,
|
||||||
|
address recipientAddress,
|
||||||
|
uint256 amount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (bool success)
|
||||||
|
{
|
||||||
|
_tokenBalances[msg.sender][ownerAddress] -= amount;
|
||||||
|
_tokenBalances[msg.sender][recipientAddress] += amount;
|
||||||
|
emit KyberBridgeTokenTransfer(
|
||||||
|
msg.sender,
|
||||||
|
ownerAddress,
|
||||||
|
recipientAddress,
|
||||||
|
amount
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tokenBalanceOf(
|
||||||
|
address ownerAddress
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256 balance)
|
||||||
|
{
|
||||||
|
return _tokenBalances[msg.sender][ownerAddress];
|
||||||
|
}
|
||||||
|
|
||||||
|
function grantTokensTo(address tokenAddress, address ownerAddress, uint256 amount)
|
||||||
|
public
|
||||||
|
payable
|
||||||
|
{
|
||||||
|
_tokenBalances[tokenAddress][ownerAddress] += amount;
|
||||||
|
if (tokenAddress != address(weth)) {
|
||||||
|
// Send back ether if not WETH.
|
||||||
|
msg.sender.transfer(msg.value);
|
||||||
|
} else {
|
||||||
|
require(msg.value == amount, "VALUE_AMOUNT_MISMATCH");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @dev overridden to point to this contract.
|
||||||
|
function _getKyberNetworkProxyAddress()
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (address)
|
||||||
|
{
|
||||||
|
return address(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @dev overridden to point to test WETH.
|
||||||
|
function _getWethAddress()
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (address)
|
||||||
|
{
|
||||||
|
return address(weth);
|
||||||
|
}
|
||||||
|
}
|
@@ -407,26 +407,26 @@ contract TestUniswapBridge is
|
|||||||
function getExchange(address tokenAddress)
|
function getExchange(address tokenAddress)
|
||||||
external
|
external
|
||||||
view
|
view
|
||||||
returns (IUniswapExchange)
|
returns (address)
|
||||||
{
|
{
|
||||||
return IUniswapExchange(_testExchanges[tokenAddress]);
|
return address(_testExchanges[tokenAddress]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @dev Use `wethToken`.
|
// @dev Use `wethToken`.
|
||||||
function getWethContract()
|
function _getWethAddress()
|
||||||
public
|
internal
|
||||||
view
|
view
|
||||||
returns (IEtherToken)
|
returns (address)
|
||||||
{
|
{
|
||||||
return IEtherToken(address(wethToken));
|
return address(wethToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @dev This contract will double as the Uniswap contract.
|
// @dev This contract will double as the Uniswap contract.
|
||||||
function getUniswapExchangeFactoryContract()
|
function _getUniswapExchangeFactoryAddress()
|
||||||
public
|
internal
|
||||||
view
|
view
|
||||||
returns (IUniswapExchangeFactory)
|
returns (address)
|
||||||
{
|
{
|
||||||
return IUniswapExchangeFactory(address(this));
|
return address(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-asset-proxy",
|
"name": "@0x/contracts-asset-proxy",
|
||||||
"version": "2.3.0-beta.1",
|
"version": "3.0.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yarn pre_build && tsc -b",
|
"build": "yarn pre_build && tsc -b",
|
||||||
"build:ci": "yarn build",
|
"build:ci": "yarn build",
|
||||||
"pre_build": "run-s compile contracts:gen generate_contract_wrappers",
|
"pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
|
||||||
"test": "yarn run_mocha",
|
"test": "yarn run_mocha",
|
||||||
"rebuild_and_test": "run-s build test",
|
"rebuild_and_test": "run-s build test",
|
||||||
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
||||||
@@ -21,21 +21,25 @@
|
|||||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||||
"compile": "sol-compiler",
|
"compile": "sol-compiler",
|
||||||
"watch": "sol-compiler -w",
|
"watch": "sol-compiler -w",
|
||||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
|
||||||
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
|
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
|
||||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||||
"coverage:report:text": "istanbul report text",
|
"coverage:report:text": "istanbul report text",
|
||||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||||
"coverage:report:lcov": "istanbul report lcov",
|
"coverage:report:lcov": "istanbul report lcov",
|
||||||
"test:circleci": "yarn test",
|
"test:circleci": "yarn test",
|
||||||
"contracts:gen": "contracts-gen",
|
"contracts:gen": "contracts-gen generate",
|
||||||
|
"contracts:copy": "contracts-gen copy",
|
||||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
||||||
"compile:truffle": "truffle compile"
|
"compile:truffle": "truffle compile",
|
||||||
|
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
|
||||||
|
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "./generated-artifacts/@(ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IERC20Bridge|IEth2Dai|IUniswapExchange|IUniswapExchangeFactory|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestERC20Bridge|TestEth2DaiBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
"publicInterfaceContracts": "ERC1155Proxy,ERC20Proxy,ERC721Proxy,MultiAssetProxy,StaticCallProxy,ERC20BridgeProxy,Eth2DaiBridge,IAssetData,IAssetProxy,UniswapBridge,KyberBridge,ChaiBridge,TestStaticCallTarget",
|
||||||
|
"abis": "./test/generated-artifacts/@(ChaiBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IChai|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -48,12 +52,15 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
|
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^4.4.0-beta.1",
|
"@0x/abi-gen": "^5.0.1",
|
||||||
"@0x/contracts-gen": "^1.1.0-beta.1",
|
"@0x/contracts-gen": "^2.0.1",
|
||||||
"@0x/contracts-test-utils": "^3.2.0-beta.1",
|
"@0x/contracts-test-utils": "^5.0.0",
|
||||||
"@0x/dev-utils": "^2.4.0-beta.1",
|
"@0x/contracts-utils": "^4.0.1",
|
||||||
"@0x/sol-compiler": "^3.2.0-beta.1",
|
"@0x/dev-utils": "^3.0.1",
|
||||||
"@0x/tslint-config": "^3.1.0-beta.1",
|
"@0x/sol-compiler": "^4.0.1",
|
||||||
|
"@0x/ts-doc-gen": "^0.0.22",
|
||||||
|
"@0x/tslint-config": "^4.0.0",
|
||||||
|
"@0x/types": "^3.1.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
@@ -61,6 +68,7 @@
|
|||||||
"chai-as-promised": "^7.1.0",
|
"chai-as-promised": "^7.1.0",
|
||||||
"chai-bignumber": "^3.0.0",
|
"chai-bignumber": "^3.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
|
"ethereumjs-util": "^5.1.1",
|
||||||
"make-promises-safe": "^1.1.0",
|
"make-promises-safe": "^1.1.0",
|
||||||
"mocha": "^6.2.0",
|
"mocha": "^6.2.0",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
@@ -68,22 +76,20 @@
|
|||||||
"solhint": "^1.4.1",
|
"solhint": "^1.4.1",
|
||||||
"truffle": "^5.0.32",
|
"truffle": "^5.0.32",
|
||||||
"tslint": "5.11.0",
|
"tslint": "5.11.0",
|
||||||
|
"typedoc": "^0.15.0",
|
||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^5.5.0-beta.1",
|
"@0x/base-contract": "^6.0.1",
|
||||||
"@0x/contracts-dev-utils": "^0.1.0-beta.1",
|
"@0x/contracts-dev-utils": "^1.0.1",
|
||||||
"@0x/contracts-erc1155": "^1.2.0-beta.1",
|
"@0x/contracts-erc1155": "^2.0.1",
|
||||||
"@0x/contracts-erc20": "^2.3.0-beta.1",
|
"@0x/contracts-erc20": "^3.0.1",
|
||||||
"@0x/contracts-erc721": "^2.2.0-beta.1",
|
"@0x/contracts-erc721": "^3.0.1",
|
||||||
"@0x/contracts-utils": "^3.3.0-beta.1",
|
"@0x/order-utils": "^10.0.0",
|
||||||
"@0x/order-utils": "^8.5.0-beta.1",
|
"@0x/typescript-typings": "^5.0.0",
|
||||||
"@0x/types": "^2.5.0-beta.1",
|
"@0x/utils": "^5.1.0",
|
||||||
"@0x/typescript-typings": "^4.4.0-beta.1",
|
"@0x/web3-wrapper": "^7.0.1",
|
||||||
"@0x/utils": "^4.6.0-beta.1",
|
"ethereum-types": "^3.0.0",
|
||||||
"@0x/web3-wrapper": "^6.1.0-beta.1",
|
|
||||||
"ethereum-types": "^2.2.0-beta.1",
|
|
||||||
"ethereumjs-util": "^5.1.1",
|
|
||||||
"lodash": "^4.17.11"
|
"lodash": "^4.17.11"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
import { ContractArtifact } from 'ethereum-types';
|
import { ContractArtifact } from 'ethereum-types';
|
||||||
|
|
||||||
|
import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json';
|
||||||
import * as ERC1155Proxy from '../generated-artifacts/ERC1155Proxy.json';
|
import * as ERC1155Proxy from '../generated-artifacts/ERC1155Proxy.json';
|
||||||
import * as ERC20BridgeProxy from '../generated-artifacts/ERC20BridgeProxy.json';
|
import * as ERC20BridgeProxy from '../generated-artifacts/ERC20BridgeProxy.json';
|
||||||
import * as ERC20Proxy from '../generated-artifacts/ERC20Proxy.json';
|
import * as ERC20Proxy from '../generated-artifacts/ERC20Proxy.json';
|
||||||
@@ -12,44 +13,23 @@ import * as ERC721Proxy from '../generated-artifacts/ERC721Proxy.json';
|
|||||||
import * as Eth2DaiBridge from '../generated-artifacts/Eth2DaiBridge.json';
|
import * as Eth2DaiBridge from '../generated-artifacts/Eth2DaiBridge.json';
|
||||||
import * as IAssetData from '../generated-artifacts/IAssetData.json';
|
import * as IAssetData from '../generated-artifacts/IAssetData.json';
|
||||||
import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json';
|
import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json';
|
||||||
import * as IAssetProxyDispatcher from '../generated-artifacts/IAssetProxyDispatcher.json';
|
import * as KyberBridge from '../generated-artifacts/KyberBridge.json';
|
||||||
import * as IAuthorizable from '../generated-artifacts/IAuthorizable.json';
|
|
||||||
import * as IERC20Bridge from '../generated-artifacts/IERC20Bridge.json';
|
|
||||||
import * as IEth2Dai from '../generated-artifacts/IEth2Dai.json';
|
|
||||||
import * as IUniswapExchange from '../generated-artifacts/IUniswapExchange.json';
|
|
||||||
import * as IUniswapExchangeFactory from '../generated-artifacts/IUniswapExchangeFactory.json';
|
|
||||||
import * as MixinAssetProxyDispatcher from '../generated-artifacts/MixinAssetProxyDispatcher.json';
|
|
||||||
import * as MixinAuthorizable from '../generated-artifacts/MixinAuthorizable.json';
|
|
||||||
import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json';
|
import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json';
|
||||||
import * as Ownable from '../generated-artifacts/Ownable.json';
|
|
||||||
import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json';
|
import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json';
|
||||||
import * as TestERC20Bridge from '../generated-artifacts/TestERC20Bridge.json';
|
|
||||||
import * as TestEth2DaiBridge from '../generated-artifacts/TestEth2DaiBridge.json';
|
|
||||||
import * as TestStaticCallTarget from '../generated-artifacts/TestStaticCallTarget.json';
|
import * as TestStaticCallTarget from '../generated-artifacts/TestStaticCallTarget.json';
|
||||||
import * as TestUniswapBridge from '../generated-artifacts/TestUniswapBridge.json';
|
|
||||||
import * as UniswapBridge from '../generated-artifacts/UniswapBridge.json';
|
import * as UniswapBridge from '../generated-artifacts/UniswapBridge.json';
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
MixinAssetProxyDispatcher: MixinAssetProxyDispatcher as ContractArtifact,
|
|
||||||
MixinAuthorizable: MixinAuthorizable as ContractArtifact,
|
|
||||||
Ownable: Ownable as ContractArtifact,
|
|
||||||
ERC1155Proxy: ERC1155Proxy as ContractArtifact,
|
ERC1155Proxy: ERC1155Proxy as ContractArtifact,
|
||||||
ERC20BridgeProxy: ERC20BridgeProxy as ContractArtifact,
|
|
||||||
ERC20Proxy: ERC20Proxy as ContractArtifact,
|
ERC20Proxy: ERC20Proxy as ContractArtifact,
|
||||||
ERC721Proxy: ERC721Proxy as ContractArtifact,
|
ERC721Proxy: ERC721Proxy as ContractArtifact,
|
||||||
MultiAssetProxy: MultiAssetProxy as ContractArtifact,
|
MultiAssetProxy: MultiAssetProxy as ContractArtifact,
|
||||||
StaticCallProxy: StaticCallProxy as ContractArtifact,
|
StaticCallProxy: StaticCallProxy as ContractArtifact,
|
||||||
|
ERC20BridgeProxy: ERC20BridgeProxy as ContractArtifact,
|
||||||
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
||||||
UniswapBridge: UniswapBridge as ContractArtifact,
|
|
||||||
IAssetData: IAssetData as ContractArtifact,
|
IAssetData: IAssetData as ContractArtifact,
|
||||||
IAssetProxy: IAssetProxy as ContractArtifact,
|
IAssetProxy: IAssetProxy as ContractArtifact,
|
||||||
IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact,
|
UniswapBridge: UniswapBridge as ContractArtifact,
|
||||||
IAuthorizable: IAuthorizable as ContractArtifact,
|
KyberBridge: KyberBridge as ContractArtifact,
|
||||||
IERC20Bridge: IERC20Bridge as ContractArtifact,
|
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||||
IEth2Dai: IEth2Dai as ContractArtifact,
|
|
||||||
IUniswapExchange: IUniswapExchange as ContractArtifact,
|
|
||||||
IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact,
|
|
||||||
TestERC20Bridge: TestERC20Bridge as ContractArtifact,
|
|
||||||
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
|
|
||||||
TestStaticCallTarget: TestStaticCallTarget as ContractArtifact,
|
TestStaticCallTarget: TestStaticCallTarget as ContractArtifact,
|
||||||
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
|
|
||||||
};
|
};
|
||||||
|
@@ -13,7 +13,9 @@ import { Web3Wrapper } from '@0x/web3-wrapper';
|
|||||||
import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts, ERC1155ProxyContract, IAssetProxyContract } from '../../src';
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { ERC1155ProxyContract, IAssetProxyContract } from './wrappers';
|
||||||
|
|
||||||
export class ERC1155ProxyWrapper {
|
export class ERC1155ProxyWrapper {
|
||||||
private readonly _tokenOwnerAddresses: string[];
|
private readonly _tokenOwnerAddresses: string[];
|
||||||
@@ -74,7 +76,7 @@ export class ERC1155ProxyWrapper {
|
|||||||
txDefaults,
|
txDefaults,
|
||||||
artifacts,
|
artifacts,
|
||||||
);
|
);
|
||||||
this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync();
|
this._proxyIdIfExists = await this._proxyContract.getProxyId().callAsync();
|
||||||
return this._proxyContract;
|
return this._proxyContract;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -111,19 +113,13 @@ export class ERC1155ProxyWrapper {
|
|||||||
this._validateProxyContractExistsOrThrow();
|
this._validateProxyContractExistsOrThrow();
|
||||||
const assetData =
|
const assetData =
|
||||||
assetData_ === undefined
|
assetData_ === undefined
|
||||||
? await this._devUtils.encodeERC1155AssetData.callAsync(
|
? await this._devUtils
|
||||||
contractAddress,
|
.encodeERC1155AssetData(contractAddress, tokensToTransfer, valuesToTransfer, receiverCallbackData)
|
||||||
tokensToTransfer,
|
.callAsync()
|
||||||
valuesToTransfer,
|
|
||||||
receiverCallbackData,
|
|
||||||
)
|
|
||||||
: assetData_;
|
: assetData_;
|
||||||
const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
const data = this._assetProxyInterface
|
||||||
assetData,
|
.transferFrom(assetData, from, to, valueMultiplier)
|
||||||
from,
|
.getABIEncodedTransactionData();
|
||||||
to,
|
|
||||||
valueMultiplier,
|
|
||||||
);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -171,19 +167,13 @@ export class ERC1155ProxyWrapper {
|
|||||||
this._validateProxyContractExistsOrThrow();
|
this._validateProxyContractExistsOrThrow();
|
||||||
const assetData =
|
const assetData =
|
||||||
assetData_ === undefined
|
assetData_ === undefined
|
||||||
? await this._devUtils.encodeERC1155AssetData.callAsync(
|
? await this._devUtils
|
||||||
contractAddress,
|
.encodeERC1155AssetData(contractAddress, tokensToTransfer, valuesToTransfer, receiverCallbackData)
|
||||||
tokensToTransfer,
|
.callAsync()
|
||||||
valuesToTransfer,
|
|
||||||
receiverCallbackData,
|
|
||||||
)
|
|
||||||
: assetData_;
|
: assetData_;
|
||||||
const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
const data = this._assetProxyInterface
|
||||||
assetData,
|
.transferFrom(assetData, from, to, valueMultiplier)
|
||||||
from,
|
.getABIEncodedTransactionData();
|
||||||
to,
|
|
||||||
valueMultiplier,
|
|
||||||
);
|
|
||||||
const txHash = await this._web3Wrapper.sendTransactionAsync({
|
const txHash = await this._web3Wrapper.sendTransactionAsync({
|
||||||
to: (this._proxyContract as ERC1155ProxyContract).address,
|
to: (this._proxyContract as ERC1155ProxyContract).address,
|
||||||
data,
|
data,
|
||||||
@@ -364,7 +354,7 @@ export class ERC1155ProxyWrapper {
|
|||||||
this._validateProxyContractExistsOrThrow();
|
this._validateProxyContractExistsOrThrow();
|
||||||
const tokenContract = this._getContractFromAddress(contractAddress);
|
const tokenContract = this._getContractFromAddress(contractAddress);
|
||||||
const operator = (this._proxyContract as ERC1155ProxyContract).address;
|
const operator = (this._proxyContract as ERC1155ProxyContract).address;
|
||||||
const didApproveAll = await tokenContract.isApprovedForAll.callAsync(userAddress, operator);
|
const didApproveAll = await tokenContract.isApprovedForAll(userAddress, operator).callAsync();
|
||||||
return didApproveAll;
|
return didApproveAll;
|
||||||
}
|
}
|
||||||
public getFungibleTokenIds(): BigNumber[] {
|
public getFungibleTokenIds(): BigNumber[] {
|
@@ -5,7 +5,9 @@ import { BigNumber } from '@0x/utils';
|
|||||||
import { ZeroExProvider } from 'ethereum-types';
|
import { ZeroExProvider } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts, ERC20ProxyContract } from '../../src';
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { ERC20ProxyContract } from './wrappers';
|
||||||
|
|
||||||
export class ERC20Wrapper {
|
export class ERC20Wrapper {
|
||||||
private readonly _tokenOwnerAddresses: string[];
|
private readonly _tokenOwnerAddresses: string[];
|
||||||
@@ -56,7 +58,7 @@ export class ERC20Wrapper {
|
|||||||
txDefaults,
|
txDefaults,
|
||||||
artifacts,
|
artifacts,
|
||||||
);
|
);
|
||||||
this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync();
|
this._proxyIdIfExists = await this._proxyContract.getProxyId().callAsync();
|
||||||
return this._proxyContract;
|
return this._proxyContract;
|
||||||
}
|
}
|
||||||
public getProxyId(): string {
|
public getProxyId(): string {
|
||||||
@@ -68,43 +70,39 @@ export class ERC20Wrapper {
|
|||||||
this._validateProxyContractExistsOrThrow();
|
this._validateProxyContractExistsOrThrow();
|
||||||
for (const dummyTokenContract of this._dummyTokenContracts) {
|
for (const dummyTokenContract of this._dummyTokenContracts) {
|
||||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||||
await dummyTokenContract.setBalance.awaitTransactionSuccessAsync(
|
await dummyTokenContract
|
||||||
tokenOwnerAddress,
|
.setBalance(tokenOwnerAddress, constants.INITIAL_ERC20_BALANCE)
|
||||||
constants.INITIAL_ERC20_BALANCE,
|
.awaitTransactionSuccessAsync({ from: this._contractOwnerAddress });
|
||||||
{ from: this._contractOwnerAddress },
|
await dummyTokenContract
|
||||||
);
|
.approve((this._proxyContract as ERC20ProxyContract).address, constants.INITIAL_ERC20_ALLOWANCE)
|
||||||
await dummyTokenContract.approve.awaitTransactionSuccessAsync(
|
.awaitTransactionSuccessAsync({ from: tokenOwnerAddress });
|
||||||
(this._proxyContract as ERC20ProxyContract).address,
|
|
||||||
constants.INITIAL_ERC20_ALLOWANCE,
|
|
||||||
{ from: tokenOwnerAddress },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async getBalanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
|
public async getBalanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
|
||||||
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
|
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
|
||||||
const balance = new BigNumber(await tokenContract.balanceOf.callAsync(userAddress));
|
const balance = new BigNumber(await tokenContract.balanceOf(userAddress).callAsync());
|
||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
|
public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
|
||||||
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
|
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
|
||||||
await tokenContract.setBalance.awaitTransactionSuccessAsync(
|
await tokenContract
|
||||||
userAddress,
|
.setBalance(userAddress, amount)
|
||||||
amount,
|
.awaitTransactionSuccessAsync(
|
||||||
{ from: this._contractOwnerAddress },
|
{ from: this._contractOwnerAddress },
|
||||||
{ pollingIntervalMs: constants.AWAIT_TRANSACTION_MINED_MS },
|
{ pollingIntervalMs: constants.AWAIT_TRANSACTION_MINED_MS },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
|
public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
|
||||||
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
|
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
|
||||||
const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
|
const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
|
||||||
const allowance = new BigNumber(await tokenContract.allowance.callAsync(userAddress, proxyAddress));
|
const allowance = new BigNumber(await tokenContract.allowance(userAddress, proxyAddress).callAsync());
|
||||||
return allowance;
|
return allowance;
|
||||||
}
|
}
|
||||||
public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
|
public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
|
||||||
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
|
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
|
||||||
const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
|
const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
|
||||||
await tokenContract.approve.awaitTransactionSuccessAsync(proxyAddress, amount, { from: userAddress });
|
await tokenContract.approve(proxyAddress, amount).awaitTransactionSuccessAsync({ from: userAddress });
|
||||||
}
|
}
|
||||||
public async getBalancesAsync(): Promise<ERC20BalancesByOwner> {
|
public async getBalancesAsync(): Promise<ERC20BalancesByOwner> {
|
||||||
this._validateDummyTokenContractsExistOrThrow();
|
this._validateDummyTokenContractsExistOrThrow();
|
||||||
@@ -113,7 +111,7 @@ export class ERC20Wrapper {
|
|||||||
const balanceInfo: Array<{ tokenOwnerAddress: string; tokenAddress: string }> = [];
|
const balanceInfo: Array<{ tokenOwnerAddress: string; tokenAddress: string }> = [];
|
||||||
for (const dummyTokenContract of this._dummyTokenContracts) {
|
for (const dummyTokenContract of this._dummyTokenContracts) {
|
||||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||||
balances.push(await dummyTokenContract.balanceOf.callAsync(tokenOwnerAddress));
|
balances.push(await dummyTokenContract.balanceOf(tokenOwnerAddress).callAsync());
|
||||||
balanceInfo.push({
|
balanceInfo.push({
|
||||||
tokenOwnerAddress,
|
tokenOwnerAddress,
|
||||||
tokenAddress: dummyTokenContract.address,
|
tokenAddress: dummyTokenContract.address,
|
||||||
@@ -147,7 +145,7 @@ export class ERC20Wrapper {
|
|||||||
return tokenAddresses;
|
return tokenAddresses;
|
||||||
}
|
}
|
||||||
private async _getTokenContractFromAssetDataAsync(assetData: string): Promise<DummyERC20TokenContract> {
|
private async _getTokenContractFromAssetDataAsync(assetData: string): Promise<DummyERC20TokenContract> {
|
||||||
const [proxyId, tokenAddress] = await this._devUtils.decodeERC20AssetData.callAsync(assetData); // tslint:disable-line:no-unused-variable
|
const [proxyId, tokenAddress] = await this._devUtils.decodeERC20AssetData(assetData).callAsync(); // tslint:disable-line:no-unused-variable
|
||||||
const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
|
const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
|
||||||
if (tokenContractIfExists === undefined) {
|
if (tokenContractIfExists === undefined) {
|
||||||
throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);
|
throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);
|
@@ -5,7 +5,9 @@ import { BigNumber } from '@0x/utils';
|
|||||||
import { ZeroExProvider } from 'ethereum-types';
|
import { ZeroExProvider } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts, ERC721ProxyContract } from '../../src';
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { ERC721ProxyContract } from './wrappers';
|
||||||
|
|
||||||
export class ERC721Wrapper {
|
export class ERC721Wrapper {
|
||||||
private readonly _tokenOwnerAddresses: string[];
|
private readonly _tokenOwnerAddresses: string[];
|
||||||
@@ -44,7 +46,7 @@ export class ERC721Wrapper {
|
|||||||
txDefaults,
|
txDefaults,
|
||||||
artifacts,
|
artifacts,
|
||||||
);
|
);
|
||||||
this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync();
|
this._proxyIdIfExists = await this._proxyContract.getProxyId().callAsync();
|
||||||
return this._proxyContract;
|
return this._proxyContract;
|
||||||
}
|
}
|
||||||
public getProxyId(): string {
|
public getProxyId(): string {
|
||||||
@@ -78,7 +80,7 @@ export class ERC721Wrapper {
|
|||||||
}
|
}
|
||||||
public async doesTokenExistAsync(tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
|
public async doesTokenExistAsync(tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
const owner = await tokenContract.ownerOf.callAsync(tokenId);
|
const owner = await tokenContract.ownerOf(tokenId).callAsync();
|
||||||
const doesExist = owner !== constants.NULL_ADDRESS;
|
const doesExist = owner !== constants.NULL_ADDRESS;
|
||||||
return doesExist;
|
return doesExist;
|
||||||
}
|
}
|
||||||
@@ -93,14 +95,14 @@ export class ERC721Wrapper {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
|
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
|
||||||
await tokenContract.setApprovalForAll.awaitTransactionSuccessAsync(proxyAddress, isApproved, {
|
await tokenContract.setApprovalForAll(proxyAddress, isApproved).awaitTransactionSuccessAsync({
|
||||||
from: ownerAddress,
|
from: ownerAddress,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public async approveAsync(to: string, tokenAddress: string, tokenId: BigNumber): Promise<void> {
|
public async approveAsync(to: string, tokenAddress: string, tokenId: BigNumber): Promise<void> {
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
|
const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
|
||||||
await tokenContract.approve.awaitTransactionSuccessAsync(to, tokenId, { from: tokenOwner });
|
await tokenContract.approve(to, tokenId).awaitTransactionSuccessAsync({ from: tokenOwner });
|
||||||
}
|
}
|
||||||
public async transferFromAsync(
|
public async transferFromAsync(
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
@@ -109,28 +111,28 @@ export class ERC721Wrapper {
|
|||||||
userAddress: string,
|
userAddress: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
await tokenContract.transferFrom.awaitTransactionSuccessAsync(currentOwner, userAddress, tokenId, {
|
await tokenContract.transferFrom(currentOwner, userAddress, tokenId).awaitTransactionSuccessAsync({
|
||||||
from: currentOwner,
|
from: currentOwner,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public async mintAsync(tokenAddress: string, tokenId: BigNumber, userAddress: string): Promise<void> {
|
public async mintAsync(tokenAddress: string, tokenId: BigNumber, userAddress: string): Promise<void> {
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
await tokenContract.mint.awaitTransactionSuccessAsync(userAddress, tokenId, {
|
await tokenContract.mint(userAddress, tokenId).awaitTransactionSuccessAsync({
|
||||||
from: this._contractOwnerAddress,
|
from: this._contractOwnerAddress,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public async burnAsync(tokenAddress: string, tokenId: BigNumber, owner: string): Promise<void> {
|
public async burnAsync(tokenAddress: string, tokenId: BigNumber, owner: string): Promise<void> {
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
await tokenContract.burn.awaitTransactionSuccessAsync(owner, tokenId, { from: this._contractOwnerAddress });
|
await tokenContract.burn(owner, tokenId).awaitTransactionSuccessAsync({ from: this._contractOwnerAddress });
|
||||||
}
|
}
|
||||||
public async ownerOfAsync(tokenAddress: string, tokenId: BigNumber): Promise<string> {
|
public async ownerOfAsync(tokenAddress: string, tokenId: BigNumber): Promise<string> {
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
const owner = await tokenContract.ownerOf.callAsync(tokenId);
|
const owner = await tokenContract.ownerOf(tokenId).callAsync();
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
public async isOwnerAsync(userAddress: string, tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
|
public async isOwnerAsync(userAddress: string, tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
const tokenOwner = await tokenContract.ownerOf.callAsync(tokenId);
|
const tokenOwner = await tokenContract.ownerOf(tokenId).callAsync();
|
||||||
const isOwner = tokenOwner === userAddress;
|
const isOwner = tokenOwner === userAddress;
|
||||||
return isOwner;
|
return isOwner;
|
||||||
}
|
}
|
||||||
@@ -138,13 +140,13 @@ export class ERC721Wrapper {
|
|||||||
this._validateProxyContractExistsOrThrow();
|
this._validateProxyContractExistsOrThrow();
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
const operator = (this._proxyContract as ERC721ProxyContract).address;
|
const operator = (this._proxyContract as ERC721ProxyContract).address;
|
||||||
const didApproveAll = await tokenContract.isApprovedForAll.callAsync(userAddress, operator);
|
const didApproveAll = await tokenContract.isApprovedForAll(userAddress, operator).callAsync();
|
||||||
return didApproveAll;
|
return didApproveAll;
|
||||||
}
|
}
|
||||||
public async isProxyApprovedAsync(tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
|
public async isProxyApprovedAsync(tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
|
||||||
this._validateProxyContractExistsOrThrow();
|
this._validateProxyContractExistsOrThrow();
|
||||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||||
const approvedAddress = await tokenContract.getApproved.callAsync(tokenId);
|
const approvedAddress = await tokenContract.getApproved(tokenId).callAsync();
|
||||||
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
|
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
|
||||||
const isProxyAnApprovedOperator = approvedAddress === proxyAddress;
|
const isProxyAnApprovedOperator = approvedAddress === proxyAddress;
|
||||||
return isProxyAnApprovedOperator;
|
return isProxyAnApprovedOperator;
|
||||||
@@ -161,7 +163,7 @@ export class ERC721Wrapper {
|
|||||||
dummyTokenContract.address
|
dummyTokenContract.address
|
||||||
];
|
];
|
||||||
for (const tokenId of initialTokenOwnerIds) {
|
for (const tokenId of initialTokenOwnerIds) {
|
||||||
tokenOwnerAddresses.push(await dummyTokenContract.ownerOf.callAsync(tokenId));
|
tokenOwnerAddresses.push(await dummyTokenContract.ownerOf(tokenId).callAsync());
|
||||||
tokenInfo.push({
|
tokenInfo.push({
|
||||||
tokenId,
|
tokenId,
|
||||||
tokenAddress: dummyTokenContract.address,
|
tokenAddress: dummyTokenContract.address,
|
@@ -1,3 +1,64 @@
|
|||||||
export * from './artifacts';
|
export { artifacts } from './artifacts';
|
||||||
export * from './wrappers';
|
export {
|
||||||
export * from '../test/utils';
|
ERC1155ProxyContract,
|
||||||
|
ERC20BridgeProxyContract,
|
||||||
|
ERC20ProxyContract,
|
||||||
|
ERC721ProxyContract,
|
||||||
|
Eth2DaiBridgeContract,
|
||||||
|
IAssetDataContract,
|
||||||
|
IAssetProxyContract,
|
||||||
|
MultiAssetProxyContract,
|
||||||
|
StaticCallProxyContract,
|
||||||
|
TestStaticCallTargetContract,
|
||||||
|
UniswapBridgeContract,
|
||||||
|
} from './wrappers';
|
||||||
|
|
||||||
|
export { ERC20Wrapper } from './erc20_wrapper';
|
||||||
|
export { ERC721Wrapper } from './erc721_wrapper';
|
||||||
|
export { ERC1155ProxyWrapper } from './erc1155_proxy_wrapper';
|
||||||
|
export { ERC1155MintableContract, Erc1155Wrapper } from '@0x/contracts-erc1155';
|
||||||
|
export { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
|
export { DummyERC721TokenContract } from '@0x/contracts-erc721';
|
||||||
|
export {
|
||||||
|
ERC1155HoldingsByOwner,
|
||||||
|
ERC20BalancesByOwner,
|
||||||
|
ERC721TokenIdsByOwner,
|
||||||
|
ERC1155FungibleHoldingsByOwner,
|
||||||
|
ERC1155NonFungibleHoldingsByOwner,
|
||||||
|
} from '@0x/contracts-test-utils';
|
||||||
|
export {
|
||||||
|
TransactionReceiptWithDecodedLogs,
|
||||||
|
Provider,
|
||||||
|
ZeroExProvider,
|
||||||
|
JSONRPCRequestPayload,
|
||||||
|
JSONRPCErrorCallback,
|
||||||
|
TransactionReceiptStatus,
|
||||||
|
JSONRPCResponsePayload,
|
||||||
|
JSONRPCResponseError,
|
||||||
|
ContractArtifact,
|
||||||
|
ContractChains,
|
||||||
|
CompilerOpts,
|
||||||
|
StandardContractOutput,
|
||||||
|
CompilerSettings,
|
||||||
|
ContractChainData,
|
||||||
|
ContractAbi,
|
||||||
|
DevdocOutput,
|
||||||
|
EvmOutput,
|
||||||
|
CompilerSettingsMetadata,
|
||||||
|
OptimizerSettings,
|
||||||
|
OutputField,
|
||||||
|
ParamDescription,
|
||||||
|
EvmBytecodeOutput,
|
||||||
|
AbiDefinition,
|
||||||
|
FunctionAbi,
|
||||||
|
EventAbi,
|
||||||
|
RevertErrorAbi,
|
||||||
|
EventParameter,
|
||||||
|
DataItem,
|
||||||
|
MethodAbi,
|
||||||
|
ConstructorAbi,
|
||||||
|
FallbackAbi,
|
||||||
|
ConstructorStateMutability,
|
||||||
|
TupleDataItem,
|
||||||
|
StateMutability,
|
||||||
|
} from 'ethereum-types';
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
* -----------------------------------------------------------------------------
|
* -----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
export * from '../generated-wrappers/chai_bridge';
|
||||||
export * from '../generated-wrappers/erc1155_proxy';
|
export * from '../generated-wrappers/erc1155_proxy';
|
||||||
export * from '../generated-wrappers/erc20_bridge_proxy';
|
export * from '../generated-wrappers/erc20_bridge_proxy';
|
||||||
export * from '../generated-wrappers/erc20_proxy';
|
export * from '../generated-wrappers/erc20_proxy';
|
||||||
@@ -10,19 +11,8 @@ export * from '../generated-wrappers/erc721_proxy';
|
|||||||
export * from '../generated-wrappers/eth2_dai_bridge';
|
export * from '../generated-wrappers/eth2_dai_bridge';
|
||||||
export * from '../generated-wrappers/i_asset_data';
|
export * from '../generated-wrappers/i_asset_data';
|
||||||
export * from '../generated-wrappers/i_asset_proxy';
|
export * from '../generated-wrappers/i_asset_proxy';
|
||||||
export * from '../generated-wrappers/i_asset_proxy_dispatcher';
|
export * from '../generated-wrappers/kyber_bridge';
|
||||||
export * from '../generated-wrappers/i_authorizable';
|
|
||||||
export * from '../generated-wrappers/i_erc20_bridge';
|
|
||||||
export * from '../generated-wrappers/i_eth2_dai';
|
|
||||||
export * from '../generated-wrappers/i_uniswap_exchange';
|
|
||||||
export * from '../generated-wrappers/i_uniswap_exchange_factory';
|
|
||||||
export * from '../generated-wrappers/mixin_asset_proxy_dispatcher';
|
|
||||||
export * from '../generated-wrappers/mixin_authorizable';
|
|
||||||
export * from '../generated-wrappers/multi_asset_proxy';
|
export * from '../generated-wrappers/multi_asset_proxy';
|
||||||
export * from '../generated-wrappers/ownable';
|
|
||||||
export * from '../generated-wrappers/static_call_proxy';
|
export * from '../generated-wrappers/static_call_proxy';
|
||||||
export * from '../generated-wrappers/test_erc20_bridge';
|
|
||||||
export * from '../generated-wrappers/test_eth2_dai_bridge';
|
|
||||||
export * from '../generated-wrappers/test_static_call_target';
|
export * from '../generated-wrappers/test_static_call_target';
|
||||||
export * from '../generated-wrappers/test_uniswap_bridge';
|
|
||||||
export * from '../generated-wrappers/uniswap_bridge';
|
export * from '../generated-wrappers/uniswap_bridge';
|
||||||
|
67
contracts/asset-proxy/test/artifacts.ts
Normal file
67
contracts/asset-proxy/test/artifacts.ts
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
import { ContractArtifact } from 'ethereum-types';
|
||||||
|
|
||||||
|
import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json';
|
||||||
|
import * as ERC1155Proxy from '../test/generated-artifacts/ERC1155Proxy.json';
|
||||||
|
import * as ERC20BridgeProxy from '../test/generated-artifacts/ERC20BridgeProxy.json';
|
||||||
|
import * as ERC20Proxy from '../test/generated-artifacts/ERC20Proxy.json';
|
||||||
|
import * as ERC721Proxy from '../test/generated-artifacts/ERC721Proxy.json';
|
||||||
|
import * as Eth2DaiBridge from '../test/generated-artifacts/Eth2DaiBridge.json';
|
||||||
|
import * as IAssetData from '../test/generated-artifacts/IAssetData.json';
|
||||||
|
import * as IAssetProxy from '../test/generated-artifacts/IAssetProxy.json';
|
||||||
|
import * as IAssetProxyDispatcher from '../test/generated-artifacts/IAssetProxyDispatcher.json';
|
||||||
|
import * as IAuthorizable from '../test/generated-artifacts/IAuthorizable.json';
|
||||||
|
import * as IChai from '../test/generated-artifacts/IChai.json';
|
||||||
|
import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json';
|
||||||
|
import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json';
|
||||||
|
import * as IKyberNetworkProxy from '../test/generated-artifacts/IKyberNetworkProxy.json';
|
||||||
|
import * as IUniswapExchange from '../test/generated-artifacts/IUniswapExchange.json';
|
||||||
|
import * as IUniswapExchangeFactory from '../test/generated-artifacts/IUniswapExchangeFactory.json';
|
||||||
|
import * as KyberBridge from '../test/generated-artifacts/KyberBridge.json';
|
||||||
|
import * as MixinAssetProxyDispatcher from '../test/generated-artifacts/MixinAssetProxyDispatcher.json';
|
||||||
|
import * as MixinAuthorizable from '../test/generated-artifacts/MixinAuthorizable.json';
|
||||||
|
import * as MultiAssetProxy from '../test/generated-artifacts/MultiAssetProxy.json';
|
||||||
|
import * as Ownable from '../test/generated-artifacts/Ownable.json';
|
||||||
|
import * as StaticCallProxy from '../test/generated-artifacts/StaticCallProxy.json';
|
||||||
|
import * as TestChaiBridge from '../test/generated-artifacts/TestChaiBridge.json';
|
||||||
|
import * as TestERC20Bridge from '../test/generated-artifacts/TestERC20Bridge.json';
|
||||||
|
import * as TestEth2DaiBridge from '../test/generated-artifacts/TestEth2DaiBridge.json';
|
||||||
|
import * as TestKyberBridge from '../test/generated-artifacts/TestKyberBridge.json';
|
||||||
|
import * as TestStaticCallTarget from '../test/generated-artifacts/TestStaticCallTarget.json';
|
||||||
|
import * as TestUniswapBridge from '../test/generated-artifacts/TestUniswapBridge.json';
|
||||||
|
import * as UniswapBridge from '../test/generated-artifacts/UniswapBridge.json';
|
||||||
|
export const artifacts = {
|
||||||
|
MixinAssetProxyDispatcher: MixinAssetProxyDispatcher as ContractArtifact,
|
||||||
|
MixinAuthorizable: MixinAuthorizable as ContractArtifact,
|
||||||
|
Ownable: Ownable as ContractArtifact,
|
||||||
|
ERC1155Proxy: ERC1155Proxy as ContractArtifact,
|
||||||
|
ERC20BridgeProxy: ERC20BridgeProxy as ContractArtifact,
|
||||||
|
ERC20Proxy: ERC20Proxy as ContractArtifact,
|
||||||
|
ERC721Proxy: ERC721Proxy as ContractArtifact,
|
||||||
|
MultiAssetProxy: MultiAssetProxy as ContractArtifact,
|
||||||
|
StaticCallProxy: StaticCallProxy as ContractArtifact,
|
||||||
|
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||||
|
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
||||||
|
KyberBridge: KyberBridge as ContractArtifact,
|
||||||
|
UniswapBridge: UniswapBridge as ContractArtifact,
|
||||||
|
IAssetData: IAssetData as ContractArtifact,
|
||||||
|
IAssetProxy: IAssetProxy as ContractArtifact,
|
||||||
|
IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact,
|
||||||
|
IAuthorizable: IAuthorizable as ContractArtifact,
|
||||||
|
IChai: IChai as ContractArtifact,
|
||||||
|
IERC20Bridge: IERC20Bridge as ContractArtifact,
|
||||||
|
IEth2Dai: IEth2Dai as ContractArtifact,
|
||||||
|
IKyberNetworkProxy: IKyberNetworkProxy as ContractArtifact,
|
||||||
|
IUniswapExchange: IUniswapExchange as ContractArtifact,
|
||||||
|
IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact,
|
||||||
|
TestChaiBridge: TestChaiBridge as ContractArtifact,
|
||||||
|
TestERC20Bridge: TestERC20Bridge as ContractArtifact,
|
||||||
|
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
|
||||||
|
TestKyberBridge: TestKyberBridge as ContractArtifact,
|
||||||
|
TestStaticCallTarget: TestStaticCallTarget as ContractArtifact,
|
||||||
|
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
|
||||||
|
};
|
@@ -5,7 +5,9 @@ import { BigNumber } from '@0x/utils';
|
|||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts, MixinAuthorizableContract } from '../src';
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { MixinAuthorizableContract } from './wrappers';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -47,21 +49,21 @@ describe('Authorizable', () => {
|
|||||||
describe('addAuthorizedAddress', () => {
|
describe('addAuthorizedAddress', () => {
|
||||||
it('should revert if not called by owner', async () => {
|
it('should revert if not called by owner', async () => {
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
authorizable.addAuthorizedAddress.sendTransactionAsync(notOwner, { from: notOwner }),
|
authorizable.addAuthorizedAddress(notOwner).sendTransactionAsync({ from: notOwner }),
|
||||||
RevertReason.OnlyContractOwner,
|
RevertReason.OnlyContractOwner,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow owner to add an authorized address', async () => {
|
it('should allow owner to add an authorized address', async () => {
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const isAuthorized = await authorizable.authorized.callAsync(address);
|
const isAuthorized = await authorizable.authorized(address).callAsync();
|
||||||
expect(isAuthorized).to.be.true();
|
expect(isAuthorized).to.be.true();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should revert if owner attempts to authorize a duplicate address', async () => {
|
it('should revert if owner attempts to authorize a duplicate address', async () => {
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
return expectTransactionFailedAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
authorizable.addAuthorizedAddress(address).sendTransactionAsync({ from: owner }),
|
||||||
RevertReason.TargetAlreadyAuthorized,
|
RevertReason.TargetAlreadyAuthorized,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -69,23 +71,23 @@ describe('Authorizable', () => {
|
|||||||
|
|
||||||
describe('removeAuthorizedAddress', () => {
|
describe('removeAuthorizedAddress', () => {
|
||||||
it('should revert if not called by owner', async () => {
|
it('should revert if not called by owner', async () => {
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { from: notOwner }),
|
authorizable.removeAuthorizedAddress(address).sendTransactionAsync({ from: notOwner }),
|
||||||
RevertReason.OnlyContractOwner,
|
RevertReason.OnlyContractOwner,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow owner to remove an authorized address', async () => {
|
it('should allow owner to remove an authorized address', async () => {
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.removeAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const isAuthorized = await authorizable.authorized.callAsync(address);
|
const isAuthorized = await authorizable.authorized(address).callAsync();
|
||||||
expect(isAuthorized).to.be.false();
|
expect(isAuthorized).to.be.false();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should revert if owner attempts to remove an address that is not authorized', async () => {
|
it('should revert if owner attempts to remove an address that is not authorized', async () => {
|
||||||
return expectTransactionFailedAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
authorizable.removeAuthorizedAddress(address).sendTransactionAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
RevertReason.TargetNotAuthorized,
|
RevertReason.TargetNotAuthorized,
|
||||||
@@ -95,10 +97,10 @@ describe('Authorizable', () => {
|
|||||||
|
|
||||||
describe('removeAuthorizedAddressAtIndex', () => {
|
describe('removeAuthorizedAddressAtIndex', () => {
|
||||||
it('should revert if not called by owner', async () => {
|
it('should revert if not called by owner', async () => {
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const index = new BigNumber(0);
|
const index = new BigNumber(0);
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
authorizable.removeAuthorizedAddressAtIndex(address, index).sendTransactionAsync({
|
||||||
from: notOwner,
|
from: notOwner,
|
||||||
}),
|
}),
|
||||||
RevertReason.OnlyContractOwner,
|
RevertReason.OnlyContractOwner,
|
||||||
@@ -106,10 +108,10 @@ describe('Authorizable', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should revert if index is >= authorities.length', async () => {
|
it('should revert if index is >= authorities.length', async () => {
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const index = new BigNumber(1);
|
const index = new BigNumber(1);
|
||||||
return expectTransactionFailedAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
authorizable.removeAuthorizedAddressAtIndex(address, index).sendTransactionAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
RevertReason.IndexOutOfBounds,
|
RevertReason.IndexOutOfBounds,
|
||||||
@@ -119,7 +121,7 @@ describe('Authorizable', () => {
|
|||||||
it('should revert if owner attempts to remove an address that is not authorized', async () => {
|
it('should revert if owner attempts to remove an address that is not authorized', async () => {
|
||||||
const index = new BigNumber(0);
|
const index = new BigNumber(0);
|
||||||
return expectTransactionFailedAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
authorizable.removeAuthorizedAddressAtIndex(address, index).sendTransactionAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
RevertReason.TargetNotAuthorized,
|
RevertReason.TargetNotAuthorized,
|
||||||
@@ -129,11 +131,11 @@ describe('Authorizable', () => {
|
|||||||
it('should revert if address at index does not match target', async () => {
|
it('should revert if address at index does not match target', async () => {
|
||||||
const address1 = address;
|
const address1 = address;
|
||||||
const address2 = notOwner;
|
const address2 = notOwner;
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address1, { from: owner });
|
await authorizable.addAuthorizedAddress(address1).awaitTransactionSuccessAsync({ from: owner });
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address2, { from: owner });
|
await authorizable.addAuthorizedAddress(address2).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const address1Index = new BigNumber(0);
|
const address1Index = new BigNumber(0);
|
||||||
return expectTransactionFailedAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address2, address1Index, {
|
authorizable.removeAuthorizedAddressAtIndex(address2, address1Index).sendTransactionAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
RevertReason.AuthorizedAddressMismatch,
|
RevertReason.AuthorizedAddressMismatch,
|
||||||
@@ -141,26 +143,26 @@ describe('Authorizable', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should allow owner to remove an authorized address', async () => {
|
it('should allow owner to remove an authorized address', async () => {
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const index = new BigNumber(0);
|
const index = new BigNumber(0);
|
||||||
await authorizable.removeAuthorizedAddressAtIndex.awaitTransactionSuccessAsync(address, index, {
|
await authorizable.removeAuthorizedAddressAtIndex(address, index).awaitTransactionSuccessAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
});
|
});
|
||||||
const isAuthorized = await authorizable.authorized.callAsync(address);
|
const isAuthorized = await authorizable.authorized(address).callAsync();
|
||||||
expect(isAuthorized).to.be.false();
|
expect(isAuthorized).to.be.false();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getAuthorizedAddresses', () => {
|
describe('getAuthorizedAddresses', () => {
|
||||||
it('should return all authorized addresses', async () => {
|
it('should return all authorized addresses', async () => {
|
||||||
const initial = await authorizable.getAuthorizedAddresses.callAsync();
|
const initial = await authorizable.getAuthorizedAddresses().callAsync();
|
||||||
expect(initial).to.have.length(0);
|
expect(initial).to.have.length(0);
|
||||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const afterAdd = await authorizable.getAuthorizedAddresses.callAsync();
|
const afterAdd = await authorizable.getAuthorizedAddresses().callAsync();
|
||||||
expect(afterAdd).to.have.length(1);
|
expect(afterAdd).to.have.length(1);
|
||||||
expect(afterAdd).to.include(address);
|
expect(afterAdd).to.include(address);
|
||||||
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
|
await authorizable.removeAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const afterRemove = await authorizable.getAuthorizedAddresses.callAsync();
|
const afterRemove = await authorizable.getAuthorizedAddresses().callAsync();
|
||||||
expect(afterRemove).to.have.length(0);
|
expect(afterRemove).to.have.length(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
60
contracts/asset-proxy/test/chai_bridge.ts
Normal file
60
contracts/asset-proxy/test/chai_bridge.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { ERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
|
import { blockchainTests, constants, expect, randomAddress } from '@0x/contracts-test-utils';
|
||||||
|
import { AssetProxyId, RevertReason } from '@0x/types';
|
||||||
|
import { BigNumber } from '@0x/utils';
|
||||||
|
|
||||||
|
import { artifacts } from './artifacts';
|
||||||
|
import { TestChaiBridgeContract } from './wrappers';
|
||||||
|
|
||||||
|
blockchainTests.resets('ChaiBridge unit tests', env => {
|
||||||
|
let chaiBridgeContract: TestChaiBridgeContract;
|
||||||
|
let testDaiContract: ERC20TokenContract;
|
||||||
|
let fromAddress: string;
|
||||||
|
let toAddress: string;
|
||||||
|
|
||||||
|
const alwaysRevertAddress = '0x0000000000000000000000000000000000000001';
|
||||||
|
const amount = new BigNumber(1);
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
[fromAddress, toAddress] = await env.getAccountAddressesAsync();
|
||||||
|
chaiBridgeContract = await TestChaiBridgeContract.deployFrom0xArtifactAsync(
|
||||||
|
artifacts.TestChaiBridge,
|
||||||
|
env.provider,
|
||||||
|
env.txDefaults,
|
||||||
|
artifacts,
|
||||||
|
);
|
||||||
|
const testChaiDaiAddress = await chaiBridgeContract.testChaiDai().callAsync();
|
||||||
|
testDaiContract = new ERC20TokenContract(testChaiDaiAddress, env.provider, env.txDefaults);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('bridgeTransferFrom()', () => {
|
||||||
|
it('fails if not called by ERC20BridgeProxy', async () => {
|
||||||
|
return expect(
|
||||||
|
chaiBridgeContract
|
||||||
|
.bridgeTransferFrom(randomAddress(), fromAddress, toAddress, amount, constants.NULL_BYTES)
|
||||||
|
.awaitTransactionSuccessAsync({ from: alwaysRevertAddress }),
|
||||||
|
).to.revertWith(RevertReason.ChaiBridgeOnlyCallableByErc20BridgeProxy);
|
||||||
|
});
|
||||||
|
it('returns magic bytes upon success', async () => {
|
||||||
|
const magicBytes = await chaiBridgeContract
|
||||||
|
.bridgeTransferFrom(randomAddress(), fromAddress, toAddress, amount, constants.NULL_BYTES)
|
||||||
|
.callAsync();
|
||||||
|
expect(magicBytes).to.eq(AssetProxyId.ERC20Bridge);
|
||||||
|
});
|
||||||
|
it('should increase the Dai balance of `toAddress` by `amount` if successful', async () => {
|
||||||
|
const initialBalance = await testDaiContract.balanceOf(toAddress).callAsync();
|
||||||
|
await chaiBridgeContract
|
||||||
|
.bridgeTransferFrom(randomAddress(), fromAddress, toAddress, amount, constants.NULL_BYTES)
|
||||||
|
.awaitTransactionSuccessAsync();
|
||||||
|
const endBalance = await testDaiContract.balanceOf(toAddress).callAsync();
|
||||||
|
expect(endBalance).to.bignumber.eq(initialBalance.plus(amount));
|
||||||
|
});
|
||||||
|
it('fails if the `chai.draw` call fails', async () => {
|
||||||
|
return expect(
|
||||||
|
chaiBridgeContract
|
||||||
|
.bridgeTransferFrom(randomAddress(), alwaysRevertAddress, toAddress, amount, constants.NULL_BYTES)
|
||||||
|
.awaitTransactionSuccessAsync(),
|
||||||
|
).to.revertWith(RevertReason.ChaiBridgeDrawDaiFailed);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -15,15 +15,19 @@ import {
|
|||||||
txDefaults,
|
txDefaults,
|
||||||
web3Wrapper,
|
web3Wrapper,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
|
import { SafeMathRevertErrors } from '@0x/contracts-utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { AssetProxyId, RevertReason } from '@0x/types';
|
import { AssetProxyId, RevertReason } from '@0x/types';
|
||||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||||
import * as ethUtil from 'ethereumjs-util';
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts, ERC1155ProxyContract, ERC1155ProxyWrapper, IAssetDataContract } from '../src';
|
import { ERC1155ProxyWrapper } from '../src/erc1155_proxy_wrapper';
|
||||||
|
import { ERC1155ProxyContract, IAssetDataContract } from '../src/wrappers';
|
||||||
|
|
||||||
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -74,8 +78,8 @@ describe('ERC1155Proxy', () => {
|
|||||||
const usedAddresses = ([owner, notAuthorized, authorized, spender, receiver] = _.slice(accounts, 0, 5));
|
const usedAddresses = ([owner, notAuthorized, authorized, spender, receiver] = _.slice(accounts, 0, 5));
|
||||||
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
|
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
|
||||||
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
|
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
|
||||||
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(authorized, { from: owner });
|
await erc1155Proxy.addAuthorizedAddress(authorized).awaitTransactionSuccessAsync({ from: owner });
|
||||||
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(erc1155Proxy.address, { from: owner });
|
await erc1155Proxy.addAuthorizedAddress(erc1155Proxy.address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
// deploy & configure ERC1155 tokens and receiver
|
// deploy & configure ERC1155 tokens and receiver
|
||||||
[erc1155Wrapper] = await erc1155ProxyWrapper.deployDummyContractsAsync();
|
[erc1155Wrapper] = await erc1155ProxyWrapper.deployDummyContractsAsync();
|
||||||
erc1155Contract = erc1155Wrapper.getContract();
|
erc1155Contract = erc1155Wrapper.getContract();
|
||||||
@@ -119,7 +123,7 @@ describe('ERC1155Proxy', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should have an id of 0xa7cb5fb7', async () => {
|
it('should have an id of 0xa7cb5fb7', async () => {
|
||||||
const proxyId = await erc1155Proxy.getProxyId.callAsync();
|
const proxyId = await erc1155Proxy.getProxyId().callAsync();
|
||||||
const expectedProxyId = AssetProxyId.ERC1155;
|
const expectedProxyId = AssetProxyId.ERC1155;
|
||||||
expect(proxyId).to.equal(expectedProxyId);
|
expect(proxyId).to.equal(expectedProxyId);
|
||||||
});
|
});
|
||||||
@@ -634,12 +638,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
return value.times(valueMultiplier);
|
return value.times(valueMultiplier);
|
||||||
});
|
});
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
const extraData = '0102030405060708091001020304050607080910010203040506070809100102';
|
const extraData = '0102030405060708091001020304050607080910010203040506070809100102';
|
||||||
const assetDataWithExtraData = `${assetData}${extraData}`;
|
const assetDataWithExtraData = `${assetData}${extraData}`;
|
||||||
// check balances before transfer
|
// check balances before transfer
|
||||||
@@ -694,14 +700,16 @@ describe('ERC1155Proxy', () => {
|
|||||||
// create token
|
// create token
|
||||||
await erc1155Wrapper
|
await erc1155Wrapper
|
||||||
.getContract()
|
.getContract()
|
||||||
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
|
.createWithType(tokenToCreate, tokenUri)
|
||||||
|
.awaitTransactionSuccessAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
});
|
});
|
||||||
|
|
||||||
// mint balance for spender
|
// mint balance for spender
|
||||||
await erc1155Wrapper
|
await erc1155Wrapper
|
||||||
.getContract()
|
.getContract()
|
||||||
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
|
.mintFungible(tokenToCreate, [spender], [spenderInitialBalance])
|
||||||
|
.awaitTransactionSuccessAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -739,7 +747,7 @@ describe('ERC1155Proxy', () => {
|
|||||||
|
|
||||||
// hand encode optimized assetData because our tooling (based on LibAssetData.sol/encodeERC1155AssetData) does not use optimized encoding
|
// hand encode optimized assetData because our tooling (based on LibAssetData.sol/encodeERC1155AssetData) does not use optimized encoding
|
||||||
const assetDataContract = new IAssetDataContract(constants.NULL_ADDRESS, provider);
|
const assetDataContract = new IAssetDataContract(constants.NULL_ADDRESS, provider);
|
||||||
const selector = assetDataContract.ERC1155Assets.getSelector();
|
const selector = assetDataContract.getSelector('ERC1155Assets');
|
||||||
const assetDataWithoutContractAddress =
|
const assetDataWithoutContractAddress =
|
||||||
'0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040102030400000000000000000000000000000000000000000000000000000000';
|
'0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040102030400000000000000000000000000000000000000000000000000000000';
|
||||||
const assetData = `${selector}000000000000000000000000${erc1155ContractAddress.substr(
|
const assetData = `${selector}000000000000000000000000${erc1155ContractAddress.substr(
|
||||||
@@ -794,14 +802,16 @@ describe('ERC1155Proxy', () => {
|
|||||||
// create token
|
// create token
|
||||||
await erc1155Wrapper
|
await erc1155Wrapper
|
||||||
.getContract()
|
.getContract()
|
||||||
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
|
.createWithType(tokenToCreate, tokenUri)
|
||||||
|
.awaitTransactionSuccessAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
});
|
});
|
||||||
|
|
||||||
// mint balance for spender
|
// mint balance for spender
|
||||||
await erc1155Wrapper
|
await erc1155Wrapper
|
||||||
.getContract()
|
.getContract()
|
||||||
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
|
.mintFungible(tokenToCreate, [spender], [spenderInitialBalance])
|
||||||
|
.awaitTransactionSuccessAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -847,12 +857,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [new BigNumber(2), new BigNumber(2)];
|
const valuesToTransfer = [new BigNumber(2), new BigNumber(2)];
|
||||||
const valueMultiplier = new BigNumber(2);
|
const valueMultiplier = new BigNumber(2);
|
||||||
// create callback data that is the encoded version of `valuesToTransfer`
|
// create callback data that is the encoded version of `valuesToTransfer`
|
||||||
const generatedAssetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const generatedAssetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// remove the function selector and contract address from check, as these change on each test
|
// remove the function selector and contract address from check, as these change on each test
|
||||||
const offsetToTokenIds = 74;
|
const offsetToTokenIds = 74;
|
||||||
const assetDataSelectorAndContractAddress = generatedAssetData.substr(0, offsetToTokenIds);
|
const assetDataSelectorAndContractAddress = generatedAssetData.substr(0, offsetToTokenIds);
|
||||||
@@ -919,14 +931,16 @@ describe('ERC1155Proxy', () => {
|
|||||||
// create token
|
// create token
|
||||||
await erc1155Wrapper
|
await erc1155Wrapper
|
||||||
.getContract()
|
.getContract()
|
||||||
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
|
.createWithType(tokenToCreate, tokenUri)
|
||||||
|
.awaitTransactionSuccessAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
});
|
});
|
||||||
|
|
||||||
// mint balance for spender
|
// mint balance for spender
|
||||||
await erc1155Wrapper
|
await erc1155Wrapper
|
||||||
.getContract()
|
.getContract()
|
||||||
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
|
.mintFungible(tokenToCreate, [spender], [spenderInitialBalance])
|
||||||
|
.awaitTransactionSuccessAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -969,12 +983,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [new BigNumber(1), new BigNumber(2)];
|
const valuesToTransfer = [new BigNumber(1), new BigNumber(2)];
|
||||||
const valueMultiplier = new BigNumber(2);
|
const valueMultiplier = new BigNumber(2);
|
||||||
// create callback data that is the encoded version of `valuesToTransfer`
|
// create callback data that is the encoded version of `valuesToTransfer`
|
||||||
const generatedAssetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const generatedAssetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// remove the function selector and contract address from check, as these change on each test
|
// remove the function selector and contract address from check, as these change on each test
|
||||||
const offsetToTokenIds = 74;
|
const offsetToTokenIds = 74;
|
||||||
const assetDataSelectorAndContractAddress = generatedAssetData.substr(0, offsetToTokenIds);
|
const assetDataSelectorAndContractAddress = generatedAssetData.substr(0, offsetToTokenIds);
|
||||||
@@ -1032,12 +1048,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1079,12 +1097,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1130,12 +1150,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1181,12 +1203,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1232,12 +1256,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1284,12 +1310,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1331,12 +1359,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1382,12 +1412,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1429,12 +1461,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
// The asset data we just generated will look like this:
|
// The asset data we just generated will look like this:
|
||||||
// a7cb5fb7
|
// a7cb5fb7
|
||||||
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
|
||||||
@@ -1480,12 +1514,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync(
|
const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync(
|
||||||
spender,
|
spender,
|
||||||
receiverContract,
|
receiverContract,
|
||||||
@@ -1511,12 +1547,14 @@ describe('ERC1155Proxy', () => {
|
|||||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||||
const valueMultiplier = valueMultiplierSmall;
|
const valueMultiplier = valueMultiplierSmall;
|
||||||
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
|
||||||
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
|
const assetData = await devUtils
|
||||||
erc1155ContractAddress,
|
.encodeERC1155AssetData(
|
||||||
tokensToTransfer,
|
erc1155ContractAddress,
|
||||||
valuesToTransfer,
|
tokensToTransfer,
|
||||||
receiverCallbackData,
|
valuesToTransfer,
|
||||||
);
|
receiverCallbackData,
|
||||||
|
)
|
||||||
|
.callAsync();
|
||||||
const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync(
|
const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync(
|
||||||
spender,
|
spender,
|
||||||
receiverContract,
|
receiverContract,
|
||||||
@@ -1640,7 +1678,7 @@ describe('ERC1155Proxy', () => {
|
|||||||
it('should propagate revert reason from erc1155 contract failure', async () => {
|
it('should propagate revert reason from erc1155 contract failure', async () => {
|
||||||
// disable transfers
|
// disable transfers
|
||||||
const shouldRejectTransfer = true;
|
const shouldRejectTransfer = true;
|
||||||
await erc1155Receiver.setRejectTransferFlag.awaitTransactionSuccessAsync(shouldRejectTransfer, {
|
await erc1155Receiver.setRejectTransferFlag(shouldRejectTransfer).awaitTransactionSuccessAsync({
|
||||||
from: owner,
|
from: owner,
|
||||||
});
|
});
|
||||||
// setup test parameters
|
// setup test parameters
|
||||||
|
@@ -3,27 +3,22 @@ import {
|
|||||||
constants,
|
constants,
|
||||||
expect,
|
expect,
|
||||||
getRandomInteger,
|
getRandomInteger,
|
||||||
hexLeftPad,
|
|
||||||
hexRightPad,
|
|
||||||
hexSlice,
|
|
||||||
Numberish,
|
Numberish,
|
||||||
randomAddress,
|
randomAddress,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
|
import { AuthorizableRevertErrors } from '@0x/contracts-utils';
|
||||||
import { AssetProxyId } from '@0x/types';
|
import { AssetProxyId } from '@0x/types';
|
||||||
import { AbiEncoder, AuthorizableRevertErrors, BigNumber, StringRevertError } from '@0x/utils';
|
import { AbiEncoder, BigNumber, hexUtils, StringRevertError } from '@0x/utils';
|
||||||
import { DecodedLogs } from 'ethereum-types';
|
import { DecodedLogs } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {
|
import { artifacts } from './artifacts';
|
||||||
artifacts,
|
|
||||||
ERC20BridgeProxyContract,
|
import { ERC20BridgeProxyContract, TestERC20BridgeContract } from './wrappers';
|
||||||
TestERC20BridgeBridgeWithdrawToEventArgs,
|
|
||||||
TestERC20BridgeContract,
|
|
||||||
} from '../src';
|
|
||||||
|
|
||||||
blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
||||||
const PROXY_ID = AssetProxyId.ERC20Bridge;
|
const PROXY_ID = AssetProxyId.ERC20Bridge;
|
||||||
const BRIDGE_SUCCESS_RETURN_DATA = hexRightPad(PROXY_ID);
|
const BRIDGE_SUCCESS_RETURN_DATA = hexUtils.rightPad(PROXY_ID);
|
||||||
let owner: string;
|
let owner: string;
|
||||||
let badCaller: string;
|
let badCaller: string;
|
||||||
let assetProxy: ERC20BridgeProxyContract;
|
let assetProxy: ERC20BridgeProxyContract;
|
||||||
@@ -44,8 +39,8 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
|||||||
env.txDefaults,
|
env.txDefaults,
|
||||||
artifacts,
|
artifacts,
|
||||||
);
|
);
|
||||||
testTokenAddress = await bridgeContract.testToken.callAsync();
|
testTokenAddress = await bridgeContract.testToken().callAsync();
|
||||||
await assetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(owner);
|
await assetProxy.addAuthorizedAddress(owner).awaitTransactionSuccessAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
interface AssetDataOpts {
|
interface AssetDataOpts {
|
||||||
@@ -102,7 +97,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function setTestTokenBalanceAsync(_owner: string, balance: Numberish): Promise<void> {
|
async function setTestTokenBalanceAsync(_owner: string, balance: Numberish): Promise<void> {
|
||||||
await bridgeContract.setTestTokenBalance.awaitTransactionSuccessAsync(_owner, new BigNumber(balance));
|
await bridgeContract.setTestTokenBalance(_owner, new BigNumber(balance)).awaitTransactionSuccessAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('transferFrom()', () => {
|
describe('transferFrom()', () => {
|
||||||
@@ -132,13 +127,9 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
|||||||
|
|
||||||
async function transferFromAsync(opts?: Partial<TransferFromOpts>, caller?: string): Promise<DecodedLogs> {
|
async function transferFromAsync(opts?: Partial<TransferFromOpts>, caller?: string): Promise<DecodedLogs> {
|
||||||
const _opts = createTransferFromOpts(opts);
|
const _opts = createTransferFromOpts(opts);
|
||||||
const { logs } = await assetProxy.transferFrom.awaitTransactionSuccessAsync(
|
const { logs } = await assetProxy
|
||||||
encodeAssetData(_opts.assetData),
|
.transferFrom(encodeAssetData(_opts.assetData), _opts.from, _opts.to, new BigNumber(_opts.amount))
|
||||||
_opts.from,
|
.awaitTransactionSuccessAsync({ from: caller });
|
||||||
_opts.to,
|
|
||||||
new BigNumber(_opts.amount),
|
|
||||||
{ from: caller },
|
|
||||||
);
|
|
||||||
return (logs as any) as DecodedLogs;
|
return (logs as any) as DecodedLogs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +155,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
|||||||
const opts = createTransferFromOpts();
|
const opts = createTransferFromOpts();
|
||||||
const logs = await transferFromAsync(opts);
|
const logs = await transferFromAsync(opts);
|
||||||
expect(logs.length).to.eq(1);
|
expect(logs.length).to.eq(1);
|
||||||
const args = logs[0].args as TestERC20BridgeBridgeWithdrawToEventArgs;
|
const args = logs[0].args;
|
||||||
expect(args.tokenAddress).to.eq(opts.assetData.tokenAddress);
|
expect(args.tokenAddress).to.eq(opts.assetData.tokenAddress);
|
||||||
expect(args.from).to.eq(opts.from);
|
expect(args.from).to.eq(opts.from);
|
||||||
expect(args.to).to.eq(opts.to);
|
expect(args.to).to.eq(opts.to);
|
||||||
@@ -179,13 +170,10 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
|||||||
|
|
||||||
it('fails if asset data is truncated', async () => {
|
it('fails if asset data is truncated', async () => {
|
||||||
const opts = createTransferFromOpts();
|
const opts = createTransferFromOpts();
|
||||||
const truncatedAssetData = hexSlice(encodeAssetData(opts.assetData), 0, -1);
|
const truncatedAssetData = hexUtils.slice(encodeAssetData(opts.assetData), 0, -1);
|
||||||
const tx = assetProxy.transferFrom.awaitTransactionSuccessAsync(
|
const tx = assetProxy
|
||||||
truncatedAssetData,
|
.transferFrom(truncatedAssetData, opts.from, opts.to, new BigNumber(opts.amount))
|
||||||
opts.from,
|
.awaitTransactionSuccessAsync();
|
||||||
opts.to,
|
|
||||||
new BigNumber(opts.amount),
|
|
||||||
);
|
|
||||||
return expect(tx).to.be.rejected();
|
return expect(tx).to.be.rejected();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -206,7 +194,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
|||||||
const tx = transferFromAsync({
|
const tx = transferFromAsync({
|
||||||
assetData: createAssetData({
|
assetData: createAssetData({
|
||||||
bridgeData: createBridgeData({
|
bridgeData: createBridgeData({
|
||||||
returnData: hexLeftPad('0x1'),
|
returnData: hexUtils.leftPad('0x1'),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@@ -219,7 +207,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
|||||||
const tx = transferFromAsync({
|
const tx = transferFromAsync({
|
||||||
assetData: createAssetData({
|
assetData: createAssetData({
|
||||||
bridgeData: createBridgeData({
|
bridgeData: createBridgeData({
|
||||||
returnData: hexRightPad('0x1'),
|
returnData: hexUtils.rightPad('0x1'),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@@ -281,18 +269,18 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
|
|||||||
it('retrieves the balance of the encoded token', async () => {
|
it('retrieves the balance of the encoded token', async () => {
|
||||||
const _owner = randomAddress();
|
const _owner = randomAddress();
|
||||||
const balance = getRandomInteger(1, 100e18);
|
const balance = getRandomInteger(1, 100e18);
|
||||||
await bridgeContract.setTestTokenBalance.awaitTransactionSuccessAsync(_owner, balance);
|
await bridgeContract.setTestTokenBalance(_owner, balance).awaitTransactionSuccessAsync();
|
||||||
const assetData = createAssetData({
|
const assetData = createAssetData({
|
||||||
tokenAddress: testTokenAddress,
|
tokenAddress: testTokenAddress,
|
||||||
});
|
});
|
||||||
const actualBalance = await assetProxy.balanceOf.callAsync(encodeAssetData(assetData), _owner);
|
const actualBalance = await assetProxy.balanceOf(encodeAssetData(assetData), _owner).callAsync();
|
||||||
expect(actualBalance).to.bignumber.eq(balance);
|
expect(actualBalance).to.bignumber.eq(balance);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getProxyId()', () => {
|
describe('getProxyId()', () => {
|
||||||
it('returns the correct proxy ID', async () => {
|
it('returns the correct proxy ID', async () => {
|
||||||
const proxyId = await assetProxy.getProxyId.callAsync();
|
const proxyId = await assetProxy.getProxyId().callAsync();
|
||||||
expect(proxyId).to.eq(PROXY_ID);
|
expect(proxyId).to.eq(PROXY_ID);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -4,28 +4,25 @@ import {
|
|||||||
expect,
|
expect,
|
||||||
filterLogsToArguments,
|
filterLogsToArguments,
|
||||||
getRandomInteger,
|
getRandomInteger,
|
||||||
hexLeftPad,
|
|
||||||
hexRandom,
|
|
||||||
Numberish,
|
Numberish,
|
||||||
randomAddress,
|
randomAddress,
|
||||||
TransactionHelper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { AssetProxyId } from '@0x/types';
|
import { AssetProxyId } from '@0x/types';
|
||||||
import { BigNumber, RawRevertError } from '@0x/utils';
|
import { BigNumber, hexUtils, RawRevertError } from '@0x/utils';
|
||||||
import { DecodedLogs } from 'ethereum-types';
|
import { DecodedLogs } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
artifacts,
|
|
||||||
TestEth2DaiBridgeContract,
|
TestEth2DaiBridgeContract,
|
||||||
TestEth2DaiBridgeEvents,
|
TestEth2DaiBridgeEvents,
|
||||||
TestEth2DaiBridgeSellAllAmountEventArgs,
|
TestEth2DaiBridgeSellAllAmountEventArgs,
|
||||||
TestEth2DaiBridgeTokenApproveEventArgs,
|
TestEth2DaiBridgeTokenApproveEventArgs,
|
||||||
TestEth2DaiBridgeTokenTransferEventArgs,
|
TestEth2DaiBridgeTokenTransferEventArgs,
|
||||||
} from '../src';
|
} from './wrappers';
|
||||||
|
|
||||||
blockchainTests.resets('Eth2DaiBridge unit tests', env => {
|
blockchainTests.resets('Eth2DaiBridge unit tests', env => {
|
||||||
const txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
|
|
||||||
let testContract: TestEth2DaiBridgeContract;
|
let testContract: TestEth2DaiBridgeContract;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
@@ -40,7 +37,9 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => {
|
|||||||
describe('isValidSignature()', () => {
|
describe('isValidSignature()', () => {
|
||||||
it('returns success bytes', async () => {
|
it('returns success bytes', async () => {
|
||||||
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
|
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
|
||||||
const result = await testContract.isValidSignature.callAsync(hexRandom(), hexRandom(_.random(0, 32)));
|
const result = await testContract
|
||||||
|
.isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32)))
|
||||||
|
.callAsync();
|
||||||
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
|
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -72,7 +71,7 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => {
|
|||||||
fillAmount: getRandomInteger(1, 100e18),
|
fillAmount: getRandomInteger(1, 100e18),
|
||||||
fromTokenBalance: getRandomInteger(1, 100e18),
|
fromTokenBalance: getRandomInteger(1, 100e18),
|
||||||
toTokentransferRevertReason: '',
|
toTokentransferRevertReason: '',
|
||||||
toTokenTransferReturnData: hexLeftPad(1),
|
toTokenTransferReturnData: hexUtils.leftPad(1),
|
||||||
...opts,
|
...opts,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -80,32 +79,30 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => {
|
|||||||
async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> {
|
async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> {
|
||||||
const _opts = createWithdrawToOpts(opts);
|
const _opts = createWithdrawToOpts(opts);
|
||||||
// Set the fill behavior.
|
// Set the fill behavior.
|
||||||
await testContract.setFillBehavior.awaitTransactionSuccessAsync(
|
await testContract
|
||||||
_opts.revertReason,
|
.setFillBehavior(_opts.revertReason, new BigNumber(_opts.fillAmount))
|
||||||
new BigNumber(_opts.fillAmount),
|
.awaitTransactionSuccessAsync();
|
||||||
);
|
|
||||||
// Create tokens and balances.
|
// Create tokens and balances.
|
||||||
if (_opts.fromTokenAddress === undefined) {
|
if (_opts.fromTokenAddress === undefined) {
|
||||||
[_opts.fromTokenAddress] = await txHelper.getResultAndReceiptAsync(
|
const createTokenFn = testContract.createToken(new BigNumber(_opts.fromTokenBalance));
|
||||||
testContract.createToken,
|
_opts.fromTokenAddress = await createTokenFn.callAsync();
|
||||||
new BigNumber(_opts.fromTokenBalance),
|
await createTokenFn.awaitTransactionSuccessAsync();
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (_opts.toTokenAddress === undefined) {
|
if (_opts.toTokenAddress === undefined) {
|
||||||
[_opts.toTokenAddress] = await txHelper.getResultAndReceiptAsync(
|
const createTokenFn = testContract.createToken(constants.ZERO_AMOUNT);
|
||||||
testContract.createToken,
|
_opts.toTokenAddress = await createTokenFn.callAsync();
|
||||||
constants.ZERO_AMOUNT,
|
await createTokenFn.awaitTransactionSuccessAsync();
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// Set the transfer behavior of `toTokenAddress`.
|
// Set the transfer behavior of `toTokenAddress`.
|
||||||
await testContract.setTransferBehavior.awaitTransactionSuccessAsync(
|
await testContract
|
||||||
_opts.toTokenAddress,
|
.setTransferBehavior(
|
||||||
_opts.toTokentransferRevertReason,
|
_opts.toTokenAddress,
|
||||||
_opts.toTokenTransferReturnData,
|
_opts.toTokentransferRevertReason,
|
||||||
);
|
_opts.toTokenTransferReturnData,
|
||||||
|
)
|
||||||
|
.awaitTransactionSuccessAsync();
|
||||||
// Call bridgeTransferFrom().
|
// Call bridgeTransferFrom().
|
||||||
const [result, { logs }] = await txHelper.getResultAndReceiptAsync(
|
const bridgeTransferFromFn = testContract.bridgeTransferFrom(
|
||||||
testContract.bridgeTransferFrom,
|
|
||||||
// "to" token address
|
// "to" token address
|
||||||
_opts.toTokenAddress,
|
_opts.toTokenAddress,
|
||||||
// Random from address.
|
// Random from address.
|
||||||
@@ -114,8 +111,10 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => {
|
|||||||
_opts.toAddress,
|
_opts.toAddress,
|
||||||
new BigNumber(_opts.amount),
|
new BigNumber(_opts.amount),
|
||||||
// ABI-encode the "from" token address as the bridge data.
|
// ABI-encode the "from" token address as the bridge data.
|
||||||
hexLeftPad(_opts.fromTokenAddress as string),
|
hexUtils.leftPad(_opts.fromTokenAddress as string),
|
||||||
);
|
);
|
||||||
|
const result = await bridgeTransferFromFn.callAsync();
|
||||||
|
const { logs } = await bridgeTransferFromFn.awaitTransactionSuccessAsync();
|
||||||
return {
|
return {
|
||||||
opts: _opts,
|
opts: _opts,
|
||||||
result,
|
result,
|
||||||
@@ -180,13 +179,13 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if `toTokenAddress.transfer()` returns false', async () => {
|
it('fails if `toTokenAddress.transfer()` returns false', async () => {
|
||||||
const opts = createWithdrawToOpts({ toTokenTransferReturnData: hexLeftPad(0) });
|
const opts = createWithdrawToOpts({ toTokenTransferReturnData: hexUtils.leftPad(0) });
|
||||||
const tx = withdrawToAsync(opts);
|
const tx = withdrawToAsync(opts);
|
||||||
return expect(tx).to.revertWith(new RawRevertError(hexLeftPad(0)));
|
return expect(tx).to.revertWith(new RawRevertError(hexUtils.leftPad(0)));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('succeeds if `toTokenAddress.transfer()` returns true', async () => {
|
it('succeeds if `toTokenAddress.transfer()` returns true', async () => {
|
||||||
await withdrawToAsync({ toTokenTransferReturnData: hexLeftPad(1) });
|
await withdrawToAsync({ toTokenTransferReturnData: hexUtils.leftPad(1) });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
272
contracts/asset-proxy/test/kyber_bridge.ts
Normal file
272
contracts/asset-proxy/test/kyber_bridge.ts
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
import {
|
||||||
|
blockchainTests,
|
||||||
|
constants,
|
||||||
|
expect,
|
||||||
|
getRandomInteger,
|
||||||
|
randomAddress,
|
||||||
|
verifyEventsFromLogs,
|
||||||
|
} from '@0x/contracts-test-utils';
|
||||||
|
import { AssetProxyId } from '@0x/types';
|
||||||
|
import { BigNumber, hexUtils } from '@0x/utils';
|
||||||
|
import { DecodedLogs } from 'ethereum-types';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { TestKyberBridgeContract, TestKyberBridgeEvents } from './wrappers';
|
||||||
|
|
||||||
|
blockchainTests.resets('KyberBridge unit tests', env => {
|
||||||
|
const KYBER_ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
|
||||||
|
let testContract: TestKyberBridgeContract;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
testContract = await TestKyberBridgeContract.deployFrom0xArtifactAsync(
|
||||||
|
artifacts.TestKyberBridge,
|
||||||
|
env.provider,
|
||||||
|
env.txDefaults,
|
||||||
|
artifacts,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isValidSignature()', () => {
|
||||||
|
it('returns success bytes', async () => {
|
||||||
|
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
|
||||||
|
const result = await testContract
|
||||||
|
.isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32)))
|
||||||
|
.callAsync();
|
||||||
|
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('bridgeTransferFrom()', () => {
|
||||||
|
let fromTokenAddress: string;
|
||||||
|
let toTokenAddress: string;
|
||||||
|
let wethAddress: string;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
wethAddress = await testContract.weth().callAsync();
|
||||||
|
fromTokenAddress = await testContract.createToken().callAsync();
|
||||||
|
await testContract.createToken().awaitTransactionSuccessAsync();
|
||||||
|
toTokenAddress = await testContract.createToken().callAsync();
|
||||||
|
await testContract.createToken().awaitTransactionSuccessAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
const STATIC_KYBER_TRADE_ARGS = {
|
||||||
|
maxBuyTokenAmount: constants.MAX_UINT256,
|
||||||
|
walletId: constants.NULL_ADDRESS,
|
||||||
|
};
|
||||||
|
|
||||||
|
interface TransferFromOpts {
|
||||||
|
toTokenAddress: string;
|
||||||
|
fromTokenAddress: string;
|
||||||
|
toAddress: string;
|
||||||
|
// Amount to pass into `bridgeTransferFrom()`
|
||||||
|
amount: BigNumber;
|
||||||
|
// Amount to convert in `trade()`.
|
||||||
|
fillAmount: BigNumber;
|
||||||
|
// Token balance of the bridge.
|
||||||
|
fromTokenBalance: BigNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TransferFromResult {
|
||||||
|
opts: TransferFromOpts;
|
||||||
|
result: string;
|
||||||
|
logs: DecodedLogs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTransferFromOpts(opts?: Partial<TransferFromOpts>): TransferFromOpts {
|
||||||
|
return {
|
||||||
|
fromTokenAddress,
|
||||||
|
toTokenAddress,
|
||||||
|
toAddress: randomAddress(),
|
||||||
|
amount: getRandomInteger(1, 10e18),
|
||||||
|
fillAmount: getRandomInteger(1, 10e18),
|
||||||
|
fromTokenBalance: getRandomInteger(1, 10e18),
|
||||||
|
...opts,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function withdrawToAsync(opts?: Partial<TransferFromOpts>): Promise<TransferFromResult> {
|
||||||
|
const _opts = createTransferFromOpts(opts);
|
||||||
|
// Fund the contract with input tokens.
|
||||||
|
await testContract
|
||||||
|
.grantTokensTo(_opts.fromTokenAddress, testContract.address, _opts.fromTokenBalance)
|
||||||
|
.awaitTransactionSuccessAsync({ value: _opts.fromTokenBalance });
|
||||||
|
// Fund the contract with output tokens.
|
||||||
|
await testContract.setNextFillAmount(_opts.fillAmount).awaitTransactionSuccessAsync({
|
||||||
|
value: _opts.toTokenAddress === wethAddress ? _opts.fillAmount : constants.ZERO_AMOUNT,
|
||||||
|
});
|
||||||
|
// Call bridgeTransferFrom().
|
||||||
|
const bridgeTransferFromFn = testContract.bridgeTransferFrom(
|
||||||
|
// Output token
|
||||||
|
_opts.toTokenAddress,
|
||||||
|
// Random maker address.
|
||||||
|
randomAddress(),
|
||||||
|
// Recipient address.
|
||||||
|
_opts.toAddress,
|
||||||
|
// Transfer amount.
|
||||||
|
_opts.amount,
|
||||||
|
// ABI-encode the input token address as the bridge data.
|
||||||
|
hexUtils.leftPad(_opts.fromTokenAddress),
|
||||||
|
);
|
||||||
|
const result = await bridgeTransferFromFn.callAsync();
|
||||||
|
const { logs } = await bridgeTransferFromFn.awaitTransactionSuccessAsync();
|
||||||
|
return {
|
||||||
|
opts: _opts,
|
||||||
|
result,
|
||||||
|
logs: (logs as any) as DecodedLogs,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMinimumConversionRate(opts: TransferFromOpts): BigNumber {
|
||||||
|
return opts.amount
|
||||||
|
.times(constants.ONE_ETHER)
|
||||||
|
.div(opts.fromTokenBalance)
|
||||||
|
.integerValue(BigNumber.ROUND_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
it('returns magic bytes on success', async () => {
|
||||||
|
const BRIDGE_SUCCESS_RETURN_DATA = AssetProxyId.ERC20Bridge;
|
||||||
|
const { result } = await withdrawToAsync();
|
||||||
|
expect(result).to.eq(BRIDGE_SUCCESS_RETURN_DATA);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can trade token -> token', async () => {
|
||||||
|
const { opts, logs } = await withdrawToAsync();
|
||||||
|
verifyEventsFromLogs(
|
||||||
|
logs,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
sellTokenAddress: opts.fromTokenAddress,
|
||||||
|
buyTokenAddress: opts.toTokenAddress,
|
||||||
|
sellAmount: opts.fromTokenBalance,
|
||||||
|
recipientAddress: opts.toAddress,
|
||||||
|
minConversionRate: getMinimumConversionRate(opts),
|
||||||
|
msgValue: constants.ZERO_AMOUNT,
|
||||||
|
...STATIC_KYBER_TRADE_ARGS,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
TestKyberBridgeEvents.KyberBridgeTrade,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can trade token -> ETH', async () => {
|
||||||
|
const { opts, logs } = await withdrawToAsync({
|
||||||
|
toTokenAddress: wethAddress,
|
||||||
|
});
|
||||||
|
verifyEventsFromLogs(
|
||||||
|
logs,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
sellTokenAddress: opts.fromTokenAddress,
|
||||||
|
buyTokenAddress: KYBER_ETH_ADDRESS,
|
||||||
|
sellAmount: opts.fromTokenBalance,
|
||||||
|
recipientAddress: testContract.address,
|
||||||
|
minConversionRate: getMinimumConversionRate(opts),
|
||||||
|
msgValue: constants.ZERO_AMOUNT,
|
||||||
|
...STATIC_KYBER_TRADE_ARGS,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
TestKyberBridgeEvents.KyberBridgeTrade,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can trade ETH -> token', async () => {
|
||||||
|
const { opts, logs } = await withdrawToAsync({
|
||||||
|
fromTokenAddress: wethAddress,
|
||||||
|
});
|
||||||
|
verifyEventsFromLogs(
|
||||||
|
logs,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
sellTokenAddress: KYBER_ETH_ADDRESS,
|
||||||
|
buyTokenAddress: opts.toTokenAddress,
|
||||||
|
sellAmount: opts.fromTokenBalance,
|
||||||
|
recipientAddress: opts.toAddress,
|
||||||
|
minConversionRate: getMinimumConversionRate(opts),
|
||||||
|
msgValue: opts.fromTokenBalance,
|
||||||
|
...STATIC_KYBER_TRADE_ARGS,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
TestKyberBridgeEvents.KyberBridgeTrade,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does nothing if bridge has no token balance', async () => {
|
||||||
|
const { logs } = await withdrawToAsync({
|
||||||
|
fromTokenBalance: constants.ZERO_AMOUNT,
|
||||||
|
});
|
||||||
|
expect(logs).to.be.length(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('only transfers the token if trading the same token', async () => {
|
||||||
|
const { opts, logs } = await withdrawToAsync({
|
||||||
|
toTokenAddress: fromTokenAddress,
|
||||||
|
});
|
||||||
|
verifyEventsFromLogs(
|
||||||
|
logs,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
tokenAddress: fromTokenAddress,
|
||||||
|
ownerAddress: testContract.address,
|
||||||
|
recipientAddress: opts.toAddress,
|
||||||
|
amount: opts.fromTokenBalance,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
TestKyberBridgeEvents.KyberBridgeTokenTransfer,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('grants Kyber an allowance when selling non-WETH', async () => {
|
||||||
|
const { opts, logs } = await withdrawToAsync();
|
||||||
|
verifyEventsFromLogs(
|
||||||
|
logs,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
tokenAddress: opts.fromTokenAddress,
|
||||||
|
ownerAddress: testContract.address,
|
||||||
|
spenderAddress: testContract.address,
|
||||||
|
allowance: constants.MAX_UINT256,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
TestKyberBridgeEvents.KyberBridgeTokenApprove,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not grant Kyber an allowance when selling WETH', async () => {
|
||||||
|
const { logs } = await withdrawToAsync({
|
||||||
|
fromTokenAddress: wethAddress,
|
||||||
|
});
|
||||||
|
verifyEventsFromLogs(logs, [], TestKyberBridgeEvents.KyberBridgeTokenApprove);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('withdraws WETH and passes it to Kyber when selling WETH', async () => {
|
||||||
|
const { opts, logs } = await withdrawToAsync({
|
||||||
|
fromTokenAddress: wethAddress,
|
||||||
|
});
|
||||||
|
expect(logs[0].event).to.eq(TestKyberBridgeEvents.KyberBridgeWethWithdraw);
|
||||||
|
expect(logs[0].args).to.deep.eq({
|
||||||
|
ownerAddress: testContract.address,
|
||||||
|
amount: opts.fromTokenBalance,
|
||||||
|
});
|
||||||
|
expect(logs[1].event).to.eq(TestKyberBridgeEvents.KyberBridgeTrade);
|
||||||
|
expect(logs[1].args.msgValue).to.bignumber.eq(opts.fromTokenBalance);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('wraps WETH and transfers it to the recipient when buyng WETH', async () => {
|
||||||
|
const { opts, logs } = await withdrawToAsync({
|
||||||
|
toTokenAddress: wethAddress,
|
||||||
|
});
|
||||||
|
expect(logs[0].event).to.eq(TestKyberBridgeEvents.KyberBridgeTokenApprove);
|
||||||
|
expect(logs[0].args.tokenAddress).to.eq(opts.fromTokenAddress);
|
||||||
|
expect(logs[1].event).to.eq(TestKyberBridgeEvents.KyberBridgeTrade);
|
||||||
|
expect(logs[1].args.recipientAddress).to.eq(testContract.address);
|
||||||
|
expect(logs[2].event).to.eq(TestKyberBridgeEvents.KyberBridgeWethDeposit);
|
||||||
|
expect(logs[2].args).to.deep.eq({
|
||||||
|
msgValue: opts.fillAmount,
|
||||||
|
ownerAddress: testContract.address,
|
||||||
|
amount: opts.fillAmount,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,9 @@ import { AbiEncoder, BigNumber } from '@0x/utils';
|
|||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as ethUtil from 'ethereumjs-util';
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
|
|
||||||
import { artifacts, IAssetProxyContract, StaticCallProxyContract, TestStaticCallTargetContract } from '../src';
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { IAssetProxyContract, StaticCallProxyContract, TestStaticCallTargetContract } from './wrappers';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -79,26 +81,21 @@ describe('StaticCallProxy', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should have an id of 0xc339d10a', async () => {
|
it('should have an id of 0xc339d10a', async () => {
|
||||||
const proxyId = await staticCallProxy.getProxyId.callAsync();
|
const proxyId = await staticCallProxy.getProxyId().callAsync();
|
||||||
const expectedProxyId = AssetProxyId.StaticCall;
|
const expectedProxyId = AssetProxyId.StaticCall;
|
||||||
expect(proxyId).to.equal(expectedProxyId);
|
expect(proxyId).to.equal(expectedProxyId);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('transferFrom', () => {
|
describe('transferFrom', () => {
|
||||||
it('should revert if assetData lies outside the bounds of calldata', async () => {
|
it('should revert if assetData lies outside the bounds of calldata', async () => {
|
||||||
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
|
const staticCallData = staticCallTarget.noInputFunction().getABIEncodedTransactionData();
|
||||||
const expectedResultHash = constants.KECCAK256_NULL;
|
const expectedResultHash = constants.KECCAK256_NULL;
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
const txData = staticCallProxy
|
||||||
);
|
.transferFrom(assetData, fromAddress, toAddress, amount)
|
||||||
const txData = staticCallProxy.transferFrom.getABIEncodedTransactionData(
|
.getABIEncodedTransactionData();
|
||||||
assetData,
|
|
||||||
fromAddress,
|
|
||||||
toAddress,
|
|
||||||
amount,
|
|
||||||
);
|
|
||||||
const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080';
|
const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080';
|
||||||
const txDataEndBuffer = ethUtil.toBuffer((txData.length - 2) / 2 - 4);
|
const txDataEndBuffer = ethUtil.toBuffer((txData.length - 2) / 2 - 4);
|
||||||
const paddedTxDataEndBuffer = ethUtil.setLengthLeft(txDataEndBuffer, 32);
|
const paddedTxDataEndBuffer = ethUtil.setLengthLeft(txDataEndBuffer, 32);
|
||||||
@@ -116,25 +113,21 @@ describe('StaticCallProxy', () => {
|
|||||||
it('should revert if the length of assetData is less than 100 bytes', async () => {
|
it('should revert if the length of assetData is less than 100 bytes', async () => {
|
||||||
const staticCallData = constants.NULL_BYTES;
|
const staticCallData = constants.NULL_BYTES;
|
||||||
const expectedResultHash = constants.KECCAK256_NULL;
|
const expectedResultHash = constants.KECCAK256_NULL;
|
||||||
const assetData = (await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = (await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync()).slice(0, -128);
|
||||||
expectedResultHash,
|
|
||||||
)).slice(0, -128);
|
|
||||||
const assetDataByteLen = (assetData.length - 2) / 2;
|
const assetDataByteLen = (assetData.length - 2) / 2;
|
||||||
expect((assetDataByteLen - 4) % 32).to.equal(0);
|
expect((assetDataByteLen - 4) % 32).to.equal(0);
|
||||||
await expectTransactionFailedWithoutReasonAsync(
|
await expectTransactionFailedWithoutReasonAsync(
|
||||||
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
|
staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should revert if the offset to `staticCallData` points to outside of assetData', async () => {
|
it('should revert if the offset to `staticCallData` points to outside of assetData', async () => {
|
||||||
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
|
const staticCallData = staticCallTarget.noInputFunction().getABIEncodedTransactionData();
|
||||||
const expectedResultHash = constants.KECCAK256_NULL;
|
const expectedResultHash = constants.KECCAK256_NULL;
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
|
||||||
);
|
|
||||||
const offsetToStaticCallData = '0000000000000000000000000000000000000000000000000000000000000060';
|
const offsetToStaticCallData = '0000000000000000000000000000000000000000000000000000000000000060';
|
||||||
const assetDataEndBuffer = ethUtil.toBuffer((assetData.length - 2) / 2 - 4);
|
const assetDataEndBuffer = ethUtil.toBuffer((assetData.length - 2) / 2 - 4);
|
||||||
const paddedAssetDataEndBuffer = ethUtil.setLengthLeft(assetDataEndBuffer, 32);
|
const paddedAssetDataEndBuffer = ethUtil.setLengthLeft(assetDataEndBuffer, 32);
|
||||||
@@ -145,94 +138,88 @@ describe('StaticCallProxy', () => {
|
|||||||
invalidOffsetToStaticCallData,
|
invalidOffsetToStaticCallData,
|
||||||
)}${newStaticCallData}`;
|
)}${newStaticCallData}`;
|
||||||
await expectTransactionFailedWithoutReasonAsync(
|
await expectTransactionFailedWithoutReasonAsync(
|
||||||
staticCallProxy.transferFrom.sendTransactionAsync(badAssetData, fromAddress, toAddress, amount),
|
staticCallProxy.transferFrom(badAssetData, fromAddress, toAddress, amount).sendTransactionAsync(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should revert if the callTarget attempts to write to state', async () => {
|
it('should revert if the callTarget attempts to write to state', async () => {
|
||||||
const staticCallData = staticCallTarget.updateState.getABIEncodedTransactionData();
|
const staticCallData = staticCallTarget.updateState().getABIEncodedTransactionData();
|
||||||
const expectedResultHash = constants.KECCAK256_NULL;
|
const expectedResultHash = constants.KECCAK256_NULL;
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
|
||||||
);
|
|
||||||
await expectTransactionFailedWithoutReasonAsync(
|
await expectTransactionFailedWithoutReasonAsync(
|
||||||
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
|
staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should revert with data provided by the callTarget if the staticcall reverts', async () => {
|
it('should revert with data provided by the callTarget if the staticcall reverts', async () => {
|
||||||
const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1));
|
const staticCallData = staticCallTarget.assertEvenNumber(new BigNumber(1)).getABIEncodedTransactionData();
|
||||||
const expectedResultHash = constants.KECCAK256_NULL;
|
const expectedResultHash = constants.KECCAK256_NULL;
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
|
||||||
);
|
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
|
staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
|
||||||
RevertReason.TargetNotEven,
|
RevertReason.TargetNotEven,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should revert if the hash of the output is different than expected expected', async () => {
|
it('should revert if the hash of the output is different than expected expected', async () => {
|
||||||
const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0));
|
const staticCallData = staticCallTarget.isOddNumber(new BigNumber(0)).getABIEncodedTransactionData();
|
||||||
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
|
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
|
||||||
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
|
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
|
||||||
);
|
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
|
staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
|
||||||
RevertReason.UnexpectedStaticCallResult,
|
RevertReason.UnexpectedStaticCallResult,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should be successful if a function call with no inputs and no outputs is successful', async () => {
|
it('should be successful if a function call with no inputs and no outputs is successful', async () => {
|
||||||
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
|
const staticCallData = staticCallTarget.noInputFunction().getABIEncodedTransactionData();
|
||||||
const expectedResultHash = constants.KECCAK256_NULL;
|
const expectedResultHash = constants.KECCAK256_NULL;
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
await staticCallProxy
|
||||||
);
|
.transferFrom(assetData, fromAddress, toAddress, amount)
|
||||||
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
|
.awaitTransactionSuccessAsync();
|
||||||
});
|
});
|
||||||
it('should be successful if the staticCallTarget is not a contract and no return value is expected', async () => {
|
it('should be successful if the staticCallTarget is not a contract and no return value is expected', async () => {
|
||||||
const staticCallData = '0x0102030405060708';
|
const staticCallData = '0x0102030405060708';
|
||||||
const expectedResultHash = constants.KECCAK256_NULL;
|
const expectedResultHash = constants.KECCAK256_NULL;
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
toAddress,
|
.encodeStaticCallAssetData(toAddress, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
await staticCallProxy
|
||||||
);
|
.transferFrom(assetData, fromAddress, toAddress, amount)
|
||||||
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
|
.awaitTransactionSuccessAsync();
|
||||||
});
|
});
|
||||||
it('should be successful if a function call with one static input returns the correct value', async () => {
|
it('should be successful if a function call with one static input returns the correct value', async () => {
|
||||||
const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(1));
|
const staticCallData = staticCallTarget.isOddNumber(new BigNumber(1)).getABIEncodedTransactionData();
|
||||||
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
|
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
|
||||||
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
|
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
await staticCallProxy
|
||||||
);
|
.transferFrom(assetData, fromAddress, toAddress, amount)
|
||||||
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
|
.awaitTransactionSuccessAsync();
|
||||||
});
|
});
|
||||||
it('should be successful if a function with one dynamic input is successful', async () => {
|
it('should be successful if a function with one dynamic input is successful', async () => {
|
||||||
const dynamicInput = '0x0102030405060708';
|
const dynamicInput = '0x0102030405060708';
|
||||||
const staticCallData = staticCallTarget.dynamicInputFunction.getABIEncodedTransactionData(dynamicInput);
|
const staticCallData = staticCallTarget.dynamicInputFunction(dynamicInput).getABIEncodedTransactionData();
|
||||||
const expectedResultHash = constants.KECCAK256_NULL;
|
const expectedResultHash = constants.KECCAK256_NULL;
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
await staticCallProxy
|
||||||
);
|
.transferFrom(assetData, fromAddress, toAddress, amount)
|
||||||
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
|
.awaitTransactionSuccessAsync();
|
||||||
});
|
});
|
||||||
it('should be successful if a function call returns a complex type', async () => {
|
it('should be successful if a function call returns a complex type', async () => {
|
||||||
const a = new BigNumber(1);
|
const a = new BigNumber(1);
|
||||||
const b = new BigNumber(2);
|
const b = new BigNumber(2);
|
||||||
const staticCallData = staticCallTarget.returnComplexType.getABIEncodedTransactionData(a, b);
|
const staticCallData = staticCallTarget.returnComplexType(a, b).getABIEncodedTransactionData();
|
||||||
const abiEncoder = new AbiEncoder.DynamicBytes({
|
const abiEncoder = new AbiEncoder.DynamicBytes({
|
||||||
name: '',
|
name: '',
|
||||||
type: 'bytes',
|
type: 'bytes',
|
||||||
@@ -245,12 +232,12 @@ describe('StaticCallProxy', () => {
|
|||||||
const expectedResultHash = ethUtil.bufferToHex(
|
const expectedResultHash = ethUtil.bufferToHex(
|
||||||
ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)),
|
ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)),
|
||||||
);
|
);
|
||||||
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
|
const assetData = await devUtils
|
||||||
staticCallTarget.address,
|
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
|
||||||
staticCallData,
|
.callAsync();
|
||||||
expectedResultHash,
|
await staticCallProxy
|
||||||
);
|
.transferFrom(assetData, fromAddress, toAddress, amount)
|
||||||
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
|
.awaitTransactionSuccessAsync();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -5,19 +5,17 @@ import {
|
|||||||
filterLogs,
|
filterLogs,
|
||||||
filterLogsToArguments,
|
filterLogsToArguments,
|
||||||
getRandomInteger,
|
getRandomInteger,
|
||||||
hexLeftPad,
|
|
||||||
hexRandom,
|
|
||||||
Numberish,
|
Numberish,
|
||||||
randomAddress,
|
randomAddress,
|
||||||
TransactionHelper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { AssetProxyId } from '@0x/types';
|
import { AssetProxyId } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber, hexUtils } from '@0x/utils';
|
||||||
import { DecodedLogs } from 'ethereum-types';
|
import { DecodedLogs } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
artifacts,
|
|
||||||
TestUniswapBridgeContract,
|
TestUniswapBridgeContract,
|
||||||
TestUniswapBridgeEthToTokenTransferInputEventArgs as EthToTokenTransferInputArgs,
|
TestUniswapBridgeEthToTokenTransferInputEventArgs as EthToTokenTransferInputArgs,
|
||||||
TestUniswapBridgeEvents as ContractEvents,
|
TestUniswapBridgeEvents as ContractEvents,
|
||||||
@@ -27,10 +25,9 @@ import {
|
|||||||
TestUniswapBridgeTokenTransferEventArgs as TokenTransferArgs,
|
TestUniswapBridgeTokenTransferEventArgs as TokenTransferArgs,
|
||||||
TestUniswapBridgeWethDepositEventArgs as WethDepositArgs,
|
TestUniswapBridgeWethDepositEventArgs as WethDepositArgs,
|
||||||
TestUniswapBridgeWethWithdrawEventArgs as WethWithdrawArgs,
|
TestUniswapBridgeWethWithdrawEventArgs as WethWithdrawArgs,
|
||||||
} from '../src';
|
} from './wrappers';
|
||||||
|
|
||||||
blockchainTests.resets('UniswapBridge unit tests', env => {
|
blockchainTests.resets('UniswapBridge unit tests', env => {
|
||||||
const txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
|
|
||||||
let testContract: TestUniswapBridgeContract;
|
let testContract: TestUniswapBridgeContract;
|
||||||
let wethTokenAddress: string;
|
let wethTokenAddress: string;
|
||||||
|
|
||||||
@@ -41,13 +38,15 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
env.txDefaults,
|
env.txDefaults,
|
||||||
artifacts,
|
artifacts,
|
||||||
);
|
);
|
||||||
wethTokenAddress = await testContract.wethToken.callAsync();
|
wethTokenAddress = await testContract.wethToken().callAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isValidSignature()', () => {
|
describe('isValidSignature()', () => {
|
||||||
it('returns success bytes', async () => {
|
it('returns success bytes', async () => {
|
||||||
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
|
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
|
||||||
const result = await testContract.isValidSignature.callAsync(hexRandom(), hexRandom(_.random(0, 32)));
|
const result = await testContract
|
||||||
|
.isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32)))
|
||||||
|
.callAsync();
|
||||||
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
|
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -89,35 +88,35 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
|
|
||||||
async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> {
|
async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> {
|
||||||
const _opts = createWithdrawToOpts(opts);
|
const _opts = createWithdrawToOpts(opts);
|
||||||
|
const callData = { value: new BigNumber(_opts.exchangeFillAmount) };
|
||||||
// Create the "from" token and exchange.
|
// Create the "from" token and exchange.
|
||||||
[[_opts.fromTokenAddress]] = await txHelper.getResultAndReceiptAsync(
|
const createFromTokenFn = testContract.createTokenAndExchange(
|
||||||
testContract.createTokenAndExchange,
|
|
||||||
_opts.fromTokenAddress,
|
_opts.fromTokenAddress,
|
||||||
_opts.exchangeRevertReason,
|
_opts.exchangeRevertReason,
|
||||||
{ value: new BigNumber(_opts.exchangeFillAmount) },
|
|
||||||
);
|
);
|
||||||
|
[_opts.fromTokenAddress] = await createFromTokenFn.callAsync(callData);
|
||||||
|
await createFromTokenFn.awaitTransactionSuccessAsync(callData);
|
||||||
|
|
||||||
// Create the "to" token and exchange.
|
// Create the "to" token and exchange.
|
||||||
[[_opts.toTokenAddress]] = await txHelper.getResultAndReceiptAsync(
|
const createToTokenFn = testContract.createTokenAndExchange(
|
||||||
testContract.createTokenAndExchange,
|
|
||||||
_opts.toTokenAddress,
|
_opts.toTokenAddress,
|
||||||
_opts.exchangeRevertReason,
|
_opts.exchangeRevertReason,
|
||||||
{ value: new BigNumber(_opts.exchangeFillAmount) },
|
|
||||||
);
|
|
||||||
await testContract.setTokenRevertReason.awaitTransactionSuccessAsync(
|
|
||||||
_opts.toTokenAddress,
|
|
||||||
_opts.toTokenRevertReason,
|
|
||||||
);
|
|
||||||
await testContract.setTokenRevertReason.awaitTransactionSuccessAsync(
|
|
||||||
_opts.fromTokenAddress,
|
|
||||||
_opts.fromTokenRevertReason,
|
|
||||||
);
|
);
|
||||||
|
[_opts.toTokenAddress] = await createToTokenFn.callAsync(callData);
|
||||||
|
await createToTokenFn.awaitTransactionSuccessAsync(callData);
|
||||||
|
|
||||||
|
await testContract
|
||||||
|
.setTokenRevertReason(_opts.toTokenAddress, _opts.toTokenRevertReason)
|
||||||
|
.awaitTransactionSuccessAsync();
|
||||||
|
await testContract
|
||||||
|
.setTokenRevertReason(_opts.fromTokenAddress, _opts.fromTokenRevertReason)
|
||||||
|
.awaitTransactionSuccessAsync();
|
||||||
// Set the token balance for the token we're converting from.
|
// Set the token balance for the token we're converting from.
|
||||||
await testContract.setTokenBalance.awaitTransactionSuccessAsync(_opts.fromTokenAddress, {
|
await testContract.setTokenBalance(_opts.fromTokenAddress).awaitTransactionSuccessAsync({
|
||||||
value: new BigNumber(_opts.fromTokenBalance),
|
value: new BigNumber(_opts.fromTokenBalance),
|
||||||
});
|
});
|
||||||
// Call bridgeTransferFrom().
|
// Call bridgeTransferFrom().
|
||||||
const [result, receipt] = await txHelper.getResultAndReceiptAsync(
|
const bridgeTransferFromFn = testContract.bridgeTransferFrom(
|
||||||
testContract.bridgeTransferFrom,
|
|
||||||
// The "to" token address.
|
// The "to" token address.
|
||||||
_opts.toTokenAddress,
|
_opts.toTokenAddress,
|
||||||
// The "from" address.
|
// The "from" address.
|
||||||
@@ -127,8 +126,10 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
// The amount to transfer to "to"
|
// The amount to transfer to "to"
|
||||||
new BigNumber(_opts.amount),
|
new BigNumber(_opts.amount),
|
||||||
// ABI-encoded "from" token address.
|
// ABI-encoded "from" token address.
|
||||||
hexLeftPad(_opts.fromTokenAddress),
|
hexUtils.leftPad(_opts.fromTokenAddress),
|
||||||
);
|
);
|
||||||
|
const result = await bridgeTransferFromFn.callAsync();
|
||||||
|
const receipt = await bridgeTransferFromFn.awaitTransactionSuccessAsync();
|
||||||
return {
|
return {
|
||||||
opts: _opts,
|
opts: _opts,
|
||||||
result,
|
result,
|
||||||
@@ -138,7 +139,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getExchangeForTokenAsync(tokenAddress: string): Promise<string> {
|
async function getExchangeForTokenAsync(tokenAddress: string): Promise<string> {
|
||||||
return testContract.getExchange.callAsync(tokenAddress);
|
return testContract.getExchange(tokenAddress).callAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
it('returns magic bytes on success', async () => {
|
it('returns magic bytes on success', async () => {
|
||||||
@@ -147,11 +148,9 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('just transfers tokens to `to` if the same tokens are in play', async () => {
|
it('just transfers tokens to `to` if the same tokens are in play', async () => {
|
||||||
const [[tokenAddress]] = await txHelper.getResultAndReceiptAsync(
|
const createTokenFn = await testContract.createTokenAndExchange(constants.NULL_ADDRESS, '');
|
||||||
testContract.createTokenAndExchange,
|
const [tokenAddress] = await createTokenFn.callAsync();
|
||||||
constants.NULL_ADDRESS,
|
await createTokenFn.awaitTransactionSuccessAsync();
|
||||||
'',
|
|
||||||
);
|
|
||||||
const { opts, result, logs } = await withdrawToAsync({
|
const { opts, result, logs } = await withdrawToAsync({
|
||||||
fromTokenAddress: tokenAddress,
|
fromTokenAddress: tokenAddress,
|
||||||
toTokenAddress: tokenAddress,
|
toTokenAddress: tokenAddress,
|
||||||
@@ -203,14 +202,16 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if "from" token does not exist', async () => {
|
it('fails if "from" token does not exist', async () => {
|
||||||
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
|
const tx = testContract
|
||||||
randomAddress(),
|
.bridgeTransferFrom(
|
||||||
randomAddress(),
|
randomAddress(),
|
||||||
randomAddress(),
|
randomAddress(),
|
||||||
getRandomInteger(1, 1e18),
|
randomAddress(),
|
||||||
hexLeftPad(randomAddress()),
|
getRandomInteger(1, 1e18),
|
||||||
);
|
hexUtils.leftPad(randomAddress()),
|
||||||
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
|
)
|
||||||
|
.awaitTransactionSuccessAsync();
|
||||||
|
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails if the exchange fails', async () => {
|
it('fails if the exchange fails', async () => {
|
||||||
@@ -218,7 +219,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
const tx = withdrawToAsync({
|
const tx = withdrawToAsync({
|
||||||
exchangeRevertReason: revertReason,
|
exchangeRevertReason: revertReason,
|
||||||
});
|
});
|
||||||
return expect(tx).to.revertWith(revertReason);
|
return expect(tx).to.eventually.be.rejectedWith(revertReason);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -275,14 +276,16 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if "from" token does not exist', async () => {
|
it('fails if "from" token does not exist', async () => {
|
||||||
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
|
const tx = testContract
|
||||||
randomAddress(),
|
.bridgeTransferFrom(
|
||||||
randomAddress(),
|
randomAddress(),
|
||||||
randomAddress(),
|
randomAddress(),
|
||||||
getRandomInteger(1, 1e18),
|
randomAddress(),
|
||||||
hexLeftPad(wethTokenAddress),
|
getRandomInteger(1, 1e18),
|
||||||
);
|
hexUtils.leftPad(wethTokenAddress),
|
||||||
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
|
)
|
||||||
|
.awaitTransactionSuccessAsync();
|
||||||
|
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails if `WETH.deposit()` fails', async () => {
|
it('fails if `WETH.deposit()` fails', async () => {
|
||||||
@@ -291,7 +294,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
toTokenAddress: wethTokenAddress,
|
toTokenAddress: wethTokenAddress,
|
||||||
toTokenRevertReason: revertReason,
|
toTokenRevertReason: revertReason,
|
||||||
});
|
});
|
||||||
return expect(tx).to.revertWith(revertReason);
|
return expect(tx).to.eventually.be.rejectedWith(revertReason);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails if the exchange fails', async () => {
|
it('fails if the exchange fails', async () => {
|
||||||
@@ -300,7 +303,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
toTokenAddress: wethTokenAddress,
|
toTokenAddress: wethTokenAddress,
|
||||||
exchangeRevertReason: revertReason,
|
exchangeRevertReason: revertReason,
|
||||||
});
|
});
|
||||||
return expect(tx).to.revertWith(revertReason);
|
return expect(tx).to.eventually.be.rejectedWith(revertReason);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -333,14 +336,16 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if "to" token does not exist', async () => {
|
it('fails if "to" token does not exist', async () => {
|
||||||
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
|
const tx = testContract
|
||||||
wethTokenAddress,
|
.bridgeTransferFrom(
|
||||||
randomAddress(),
|
wethTokenAddress,
|
||||||
randomAddress(),
|
randomAddress(),
|
||||||
getRandomInteger(1, 1e18),
|
randomAddress(),
|
||||||
hexLeftPad(randomAddress()),
|
getRandomInteger(1, 1e18),
|
||||||
);
|
hexUtils.leftPad(randomAddress()),
|
||||||
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
|
)
|
||||||
|
.awaitTransactionSuccessAsync();
|
||||||
|
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails if the `WETH.withdraw()` fails', async () => {
|
it('fails if the `WETH.withdraw()` fails', async () => {
|
||||||
@@ -349,7 +354,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
fromTokenAddress: wethTokenAddress,
|
fromTokenAddress: wethTokenAddress,
|
||||||
fromTokenRevertReason: revertReason,
|
fromTokenRevertReason: revertReason,
|
||||||
});
|
});
|
||||||
return expect(tx).to.revertWith(revertReason);
|
return expect(tx).to.eventually.be.rejectedWith(revertReason);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails if the exchange fails', async () => {
|
it('fails if the exchange fails', async () => {
|
||||||
@@ -358,7 +363,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
|
|||||||
fromTokenAddress: wethTokenAddress,
|
fromTokenAddress: wethTokenAddress,
|
||||||
exchangeRevertReason: revertReason,
|
exchangeRevertReason: revertReason,
|
||||||
});
|
});
|
||||||
return expect(tx).to.revertWith(revertReason);
|
return expect(tx).to.eventually.be.rejectedWith(revertReason);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
export * from './erc20_wrapper';
|
|
||||||
export * from './erc721_wrapper';
|
|
||||||
export * from './erc1155_proxy_wrapper';
|
|
34
contracts/asset-proxy/test/wrappers.ts
Normal file
34
contracts/asset-proxy/test/wrappers.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
export * from '../test/generated-wrappers/chai_bridge';
|
||||||
|
export * from '../test/generated-wrappers/erc1155_proxy';
|
||||||
|
export * from '../test/generated-wrappers/erc20_bridge_proxy';
|
||||||
|
export * from '../test/generated-wrappers/erc20_proxy';
|
||||||
|
export * from '../test/generated-wrappers/erc721_proxy';
|
||||||
|
export * from '../test/generated-wrappers/eth2_dai_bridge';
|
||||||
|
export * from '../test/generated-wrappers/i_asset_data';
|
||||||
|
export * from '../test/generated-wrappers/i_asset_proxy';
|
||||||
|
export * from '../test/generated-wrappers/i_asset_proxy_dispatcher';
|
||||||
|
export * from '../test/generated-wrappers/i_authorizable';
|
||||||
|
export * from '../test/generated-wrappers/i_chai';
|
||||||
|
export * from '../test/generated-wrappers/i_erc20_bridge';
|
||||||
|
export * from '../test/generated-wrappers/i_eth2_dai';
|
||||||
|
export * from '../test/generated-wrappers/i_kyber_network_proxy';
|
||||||
|
export * from '../test/generated-wrappers/i_uniswap_exchange';
|
||||||
|
export * from '../test/generated-wrappers/i_uniswap_exchange_factory';
|
||||||
|
export * from '../test/generated-wrappers/kyber_bridge';
|
||||||
|
export * from '../test/generated-wrappers/mixin_asset_proxy_dispatcher';
|
||||||
|
export * from '../test/generated-wrappers/mixin_authorizable';
|
||||||
|
export * from '../test/generated-wrappers/multi_asset_proxy';
|
||||||
|
export * from '../test/generated-wrappers/ownable';
|
||||||
|
export * from '../test/generated-wrappers/static_call_proxy';
|
||||||
|
export * from '../test/generated-wrappers/test_chai_bridge';
|
||||||
|
export * from '../test/generated-wrappers/test_erc20_bridge';
|
||||||
|
export * from '../test/generated-wrappers/test_eth2_dai_bridge';
|
||||||
|
export * from '../test/generated-wrappers/test_kyber_bridge';
|
||||||
|
export * from '../test/generated-wrappers/test_static_call_target';
|
||||||
|
export * from '../test/generated-wrappers/test_uniswap_bridge';
|
||||||
|
export * from '../test/generated-wrappers/uniswap_bridge';
|
@@ -3,6 +3,7 @@
|
|||||||
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||||
"files": [
|
"files": [
|
||||||
|
"generated-artifacts/ChaiBridge.json",
|
||||||
"generated-artifacts/ERC1155Proxy.json",
|
"generated-artifacts/ERC1155Proxy.json",
|
||||||
"generated-artifacts/ERC20BridgeProxy.json",
|
"generated-artifacts/ERC20BridgeProxy.json",
|
||||||
"generated-artifacts/ERC20Proxy.json",
|
"generated-artifacts/ERC20Proxy.json",
|
||||||
@@ -10,22 +11,40 @@
|
|||||||
"generated-artifacts/Eth2DaiBridge.json",
|
"generated-artifacts/Eth2DaiBridge.json",
|
||||||
"generated-artifacts/IAssetData.json",
|
"generated-artifacts/IAssetData.json",
|
||||||
"generated-artifacts/IAssetProxy.json",
|
"generated-artifacts/IAssetProxy.json",
|
||||||
"generated-artifacts/IAssetProxyDispatcher.json",
|
"generated-artifacts/KyberBridge.json",
|
||||||
"generated-artifacts/IAuthorizable.json",
|
|
||||||
"generated-artifacts/IERC20Bridge.json",
|
|
||||||
"generated-artifacts/IEth2Dai.json",
|
|
||||||
"generated-artifacts/IUniswapExchange.json",
|
|
||||||
"generated-artifacts/IUniswapExchangeFactory.json",
|
|
||||||
"generated-artifacts/MixinAssetProxyDispatcher.json",
|
|
||||||
"generated-artifacts/MixinAuthorizable.json",
|
|
||||||
"generated-artifacts/MultiAssetProxy.json",
|
"generated-artifacts/MultiAssetProxy.json",
|
||||||
"generated-artifacts/Ownable.json",
|
|
||||||
"generated-artifacts/StaticCallProxy.json",
|
"generated-artifacts/StaticCallProxy.json",
|
||||||
"generated-artifacts/TestERC20Bridge.json",
|
|
||||||
"generated-artifacts/TestEth2DaiBridge.json",
|
|
||||||
"generated-artifacts/TestStaticCallTarget.json",
|
"generated-artifacts/TestStaticCallTarget.json",
|
||||||
"generated-artifacts/TestUniswapBridge.json",
|
"generated-artifacts/UniswapBridge.json",
|
||||||
"generated-artifacts/UniswapBridge.json"
|
"test/generated-artifacts/ChaiBridge.json",
|
||||||
|
"test/generated-artifacts/ERC1155Proxy.json",
|
||||||
|
"test/generated-artifacts/ERC20BridgeProxy.json",
|
||||||
|
"test/generated-artifacts/ERC20Proxy.json",
|
||||||
|
"test/generated-artifacts/ERC721Proxy.json",
|
||||||
|
"test/generated-artifacts/Eth2DaiBridge.json",
|
||||||
|
"test/generated-artifacts/IAssetData.json",
|
||||||
|
"test/generated-artifacts/IAssetProxy.json",
|
||||||
|
"test/generated-artifacts/IAssetProxyDispatcher.json",
|
||||||
|
"test/generated-artifacts/IAuthorizable.json",
|
||||||
|
"test/generated-artifacts/IChai.json",
|
||||||
|
"test/generated-artifacts/IERC20Bridge.json",
|
||||||
|
"test/generated-artifacts/IEth2Dai.json",
|
||||||
|
"test/generated-artifacts/IKyberNetworkProxy.json",
|
||||||
|
"test/generated-artifacts/IUniswapExchange.json",
|
||||||
|
"test/generated-artifacts/IUniswapExchangeFactory.json",
|
||||||
|
"test/generated-artifacts/KyberBridge.json",
|
||||||
|
"test/generated-artifacts/MixinAssetProxyDispatcher.json",
|
||||||
|
"test/generated-artifacts/MixinAuthorizable.json",
|
||||||
|
"test/generated-artifacts/MultiAssetProxy.json",
|
||||||
|
"test/generated-artifacts/Ownable.json",
|
||||||
|
"test/generated-artifacts/StaticCallProxy.json",
|
||||||
|
"test/generated-artifacts/TestChaiBridge.json",
|
||||||
|
"test/generated-artifacts/TestERC20Bridge.json",
|
||||||
|
"test/generated-artifacts/TestEth2DaiBridge.json",
|
||||||
|
"test/generated-artifacts/TestKyberBridge.json",
|
||||||
|
"test/generated-artifacts/TestStaticCallTarget.json",
|
||||||
|
"test/generated-artifacts/TestUniswapBridge.json",
|
||||||
|
"test/generated-artifacts/UniswapBridge.json"
|
||||||
],
|
],
|
||||||
"exclude": ["./deploy/solc/solc_bin"]
|
"exclude": ["./deploy/solc/solc_bin"]
|
||||||
}
|
}
|
||||||
|
10
contracts/coordinator/.npmignore
Normal file
10
contracts/coordinator/.npmignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Blacklist all files
|
||||||
|
.*
|
||||||
|
*
|
||||||
|
# Whitelist lib
|
||||||
|
!lib/**/*
|
||||||
|
# Whitelist Solidity contracts
|
||||||
|
!contracts/src/**/*
|
||||||
|
# Blacklist tests in lib
|
||||||
|
/lib/test/*
|
||||||
|
# Package specific ignore
|
@@ -1,4 +1,107 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1575931811,
|
||||||
|
"version": "3.0.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "3.0.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
|
||||||
|
"pr": 2330
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Introduced new export CoordinatorRevertErrors",
|
||||||
|
"pr": 2321
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Added dependency on @0x/contracts-utils",
|
||||||
|
"pr": 2321
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add chainId to domain separator",
|
||||||
|
"pr": 1742
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Inherit Exchange domain constants from `exchange-libs` to reduce code duplication",
|
||||||
|
"pr": 1742
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Update domain separator",
|
||||||
|
"pr": 1742
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Refactor contract to use new ITransactions interface",
|
||||||
|
"pr": 1753
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add verifyingContractIfExists arg to LibEIP712CoordinatorDomain constructor",
|
||||||
|
"pr": 1753
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Remove LibZeroExTransaction contract",
|
||||||
|
"pr": 1753
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Update tests for arbitrary fee tokens (ZEIP-28).",
|
||||||
|
"pr": 1819
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Update for new `marketXOrders` consolidation.",
|
||||||
|
"pr": 2042
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Use built in selectors instead of hard coded constants",
|
||||||
|
"pr": 2055
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Compile and export all contracts, artifacts, and wrappers by default",
|
||||||
|
"pr": 2055
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575296764
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.1.0-beta.4",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575290197
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.1.0-beta.3",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1574238768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.1.0-beta.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
|
||||||
|
"pr": 2330
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Introduced new export CoordinatorRevertErrors",
|
||||||
|
"pr": 2321
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Added dependency on @0x/contracts-utils",
|
||||||
|
"pr": 2321
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1574030254
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.1.0-beta.1",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@@ -5,6 +5,40 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v3.0.1 - _December 9, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.0.0 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
|
||||||
|
* Introduced new export CoordinatorRevertErrors (#2321)
|
||||||
|
* Added dependency on @0x/contracts-utils (#2321)
|
||||||
|
* Add chainId to domain separator (#1742)
|
||||||
|
* Inherit Exchange domain constants from `exchange-libs` to reduce code duplication (#1742)
|
||||||
|
* Update domain separator (#1742)
|
||||||
|
* Refactor contract to use new ITransactions interface (#1753)
|
||||||
|
* Add verifyingContractIfExists arg to LibEIP712CoordinatorDomain constructor (#1753)
|
||||||
|
* Remove LibZeroExTransaction contract (#1753)
|
||||||
|
* Update tests for arbitrary fee tokens (ZEIP-28). (#1819)
|
||||||
|
* Update for new `marketXOrders` consolidation. (#2042)
|
||||||
|
* Use built in selectors instead of hard coded constants (#2055)
|
||||||
|
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
|
||||||
|
|
||||||
|
## v2.1.0-beta.4 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.1.0-beta.3 - _November 20, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.1.0-beta.2 - _November 17, 2019_
|
||||||
|
|
||||||
|
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
|
||||||
|
* Introduced new export CoordinatorRevertErrors (#2321)
|
||||||
|
* Added dependency on @0x/contracts-utils (#2321)
|
||||||
|
|
||||||
## v2.1.0-beta.1 - _November 7, 2019_
|
## v2.1.0-beta.1 - _November 7, 2019_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"artifactsDir": "./generated-artifacts",
|
"artifactsDir": "./test/generated-artifacts",
|
||||||
"contractsDir": "./contracts",
|
"contractsDir": "./contracts",
|
||||||
"useDockerisedSolc": false,
|
"useDockerisedSolc": false,
|
||||||
"compilerSettings": {
|
"compilerSettings": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-coordinator",
|
"name": "@0x/contracts-coordinator",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "3.0.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yarn pre_build && tsc -b",
|
"build": "yarn pre_build && tsc -b",
|
||||||
"build:ci": "yarn build",
|
"build:ci": "yarn build",
|
||||||
"pre_build": "run-s compile contracts:gen generate_contract_wrappers",
|
"pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
|
||||||
"test": "yarn run_mocha",
|
"test": "yarn run_mocha",
|
||||||
"rebuild_and_test": "run-s build test",
|
"rebuild_and_test": "run-s build test",
|
||||||
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
||||||
@@ -21,21 +21,25 @@
|
|||||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||||
"compile": "sol-compiler",
|
"compile": "sol-compiler",
|
||||||
"watch": "sol-compiler -w",
|
"watch": "sol-compiler -w",
|
||||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
|
||||||
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
|
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
|
||||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||||
"coverage:report:text": "istanbul report text",
|
"coverage:report:text": "istanbul report text",
|
||||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||||
"coverage:report:lcov": "istanbul report lcov",
|
"coverage:report:lcov": "istanbul report lcov",
|
||||||
"test:circleci": "yarn test",
|
"test:circleci": "yarn test",
|
||||||
"contracts:gen": "contracts-gen",
|
"contracts:gen": "contracts-gen generate",
|
||||||
|
"contracts:copy": "contracts-gen copy",
|
||||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
||||||
"compile:truffle": "truffle compile"
|
"compile:truffle": "truffle compile",
|
||||||
|
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
|
||||||
|
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry|ICoordinatorApprovalVerifier|ICoordinatorCore|ICoordinatorRegistryCore|ICoordinatorSignatureValidator|LibConstants|LibCoordinatorApproval|LibCoordinatorRichErrors|LibEIP712CoordinatorDomain|MixinCoordinatorApprovalVerifier|MixinCoordinatorCore|MixinCoordinatorRegistryCore|MixinSignatureValidator).json",
|
"publicInterfaceContracts": "Coordinator,CoordinatorRegistry,LibCoordinatorApproval,LibCoordinatorRichErrors,LibEIP712CoordinatorDomain,LibConstants",
|
||||||
|
"abis": "./test/generated-artifacts/@(Coordinator|CoordinatorRegistry|ICoordinatorApprovalVerifier|ICoordinatorCore|ICoordinatorRegistryCore|ICoordinatorSignatureValidator|LibConstants|LibCoordinatorApproval|LibCoordinatorRichErrors|LibEIP712CoordinatorDomain|MixinCoordinatorApprovalVerifier|MixinCoordinatorCore|MixinCoordinatorRegistryCore|MixinSignatureValidator).json",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -48,17 +52,19 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^4.4.0-beta.1",
|
"@0x/abi-gen": "^5.0.1",
|
||||||
"@0x/contracts-asset-proxy": "^2.3.0-beta.1",
|
"@0x/contracts-asset-proxy": "^3.0.1",
|
||||||
"@0x/contracts-dev-utils": "^0.1.0-beta.1",
|
"@0x/contracts-dev-utils": "^1.0.1",
|
||||||
"@0x/contracts-erc20": "^2.3.0-beta.1",
|
"@0x/contracts-erc20": "^3.0.1",
|
||||||
"@0x/contracts-exchange": "^2.2.0-beta.1",
|
"@0x/contracts-exchange": "^3.0.1",
|
||||||
"@0x/contracts-gen": "^1.1.0-beta.1",
|
"@0x/contracts-gen": "^2.0.1",
|
||||||
"@0x/contracts-test-utils": "^3.2.0-beta.1",
|
"@0x/contracts-test-utils": "^5.0.0",
|
||||||
"@0x/dev-utils": "^2.4.0-beta.1",
|
"@0x/dev-utils": "^3.0.1",
|
||||||
"@0x/order-utils": "^8.5.0-beta.1",
|
"@0x/order-utils": "^10.0.0",
|
||||||
"@0x/sol-compiler": "^3.2.0-beta.1",
|
"@0x/sol-compiler": "^4.0.1",
|
||||||
"@0x/tslint-config": "^3.1.0-beta.1",
|
"@0x/ts-doc-gen": "^0.0.22",
|
||||||
|
"@0x/tslint-config": "^4.0.0",
|
||||||
|
"@0x/web3-wrapper": "^7.0.1",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
@@ -74,16 +80,20 @@
|
|||||||
"solhint": "^1.4.1",
|
"solhint": "^1.4.1",
|
||||||
"truffle": "^5.0.32",
|
"truffle": "^5.0.32",
|
||||||
"tslint": "5.11.0",
|
"tslint": "5.11.0",
|
||||||
|
"typedoc": "^0.15.0",
|
||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^5.5.0-beta.1",
|
"@0x/assert": "^3.0.1",
|
||||||
"@0x/types": "^2.5.0-beta.1",
|
"@0x/base-contract": "^6.0.1",
|
||||||
"@0x/typescript-typings": "^4.4.0-beta.1",
|
"@0x/contract-addresses": "^4.0.0",
|
||||||
"@0x/utils": "^4.6.0-beta.1",
|
"@0x/contracts-utils": "^4.0.1",
|
||||||
"@0x/web3-wrapper": "^6.1.0-beta.1",
|
"@0x/json-schemas": "^5.0.1",
|
||||||
"ethereum-types": "^2.2.0-beta.1",
|
"@0x/types": "^3.1.0",
|
||||||
"ethereumjs-util": "^5.1.1"
|
"@0x/typescript-typings": "^5.0.0",
|
||||||
|
"@0x/utils": "^5.1.0",
|
||||||
|
"ethereum-types": "^3.0.0",
|
||||||
|
"http-status-codes": "^1.3.2"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
import { hexConcat, signingUtils } from '@0x/contracts-test-utils';
|
import { signingUtils } from '@0x/contracts-test-utils';
|
||||||
import { SignatureType, SignedZeroExTransaction } from '@0x/types';
|
import { SignatureType, SignedZeroExTransaction } from '@0x/types';
|
||||||
|
import { hexUtils } from '@0x/utils';
|
||||||
|
|
||||||
import { hashUtils, SignedCoordinatorApproval } from './index';
|
import { hashUtils } from './hash_utils';
|
||||||
|
import { SignedCoordinatorApproval } from './types';
|
||||||
|
|
||||||
export class ApprovalFactory {
|
export class ApprovalFactory {
|
||||||
private readonly _privateKey: Buffer;
|
private readonly _privateKey: Buffer;
|
||||||
@@ -12,17 +14,21 @@ export class ApprovalFactory {
|
|||||||
this._verifyingContractAddress = verifyingContract;
|
this._verifyingContractAddress = verifyingContract;
|
||||||
}
|
}
|
||||||
|
|
||||||
public newSignedApproval(
|
public async newSignedApprovalAsync(
|
||||||
transaction: SignedZeroExTransaction,
|
transaction: SignedZeroExTransaction,
|
||||||
txOrigin: string,
|
txOrigin: string,
|
||||||
signatureType: SignatureType = SignatureType.EthSign,
|
signatureType: SignatureType = SignatureType.EthSign,
|
||||||
): SignedCoordinatorApproval {
|
): Promise<SignedCoordinatorApproval> {
|
||||||
const approvalHashBuff = hashUtils.getApprovalHashBuffer(transaction, this._verifyingContractAddress, txOrigin);
|
const approvalHashBuff = await hashUtils.getApprovalHashBufferAsync(
|
||||||
|
transaction,
|
||||||
|
this._verifyingContractAddress,
|
||||||
|
txOrigin,
|
||||||
|
);
|
||||||
const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType);
|
const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType);
|
||||||
const signedApproval = {
|
const signedApproval = {
|
||||||
txOrigin,
|
txOrigin,
|
||||||
transaction,
|
transaction,
|
||||||
signature: hexConcat(signatureBuff),
|
signature: hexUtils.concat(signatureBuff),
|
||||||
};
|
};
|
||||||
return signedApproval;
|
return signedApproval;
|
||||||
}
|
}
|
@@ -7,31 +7,15 @@ import { ContractArtifact } from 'ethereum-types';
|
|||||||
|
|
||||||
import * as Coordinator from '../generated-artifacts/Coordinator.json';
|
import * as Coordinator from '../generated-artifacts/Coordinator.json';
|
||||||
import * as CoordinatorRegistry from '../generated-artifacts/CoordinatorRegistry.json';
|
import * as CoordinatorRegistry from '../generated-artifacts/CoordinatorRegistry.json';
|
||||||
import * as ICoordinatorApprovalVerifier from '../generated-artifacts/ICoordinatorApprovalVerifier.json';
|
|
||||||
import * as ICoordinatorCore from '../generated-artifacts/ICoordinatorCore.json';
|
|
||||||
import * as ICoordinatorRegistryCore from '../generated-artifacts/ICoordinatorRegistryCore.json';
|
|
||||||
import * as ICoordinatorSignatureValidator from '../generated-artifacts/ICoordinatorSignatureValidator.json';
|
|
||||||
import * as LibConstants from '../generated-artifacts/LibConstants.json';
|
import * as LibConstants from '../generated-artifacts/LibConstants.json';
|
||||||
import * as LibCoordinatorApproval from '../generated-artifacts/LibCoordinatorApproval.json';
|
import * as LibCoordinatorApproval from '../generated-artifacts/LibCoordinatorApproval.json';
|
||||||
import * as LibCoordinatorRichErrors from '../generated-artifacts/LibCoordinatorRichErrors.json';
|
import * as LibCoordinatorRichErrors from '../generated-artifacts/LibCoordinatorRichErrors.json';
|
||||||
import * as LibEIP712CoordinatorDomain from '../generated-artifacts/LibEIP712CoordinatorDomain.json';
|
import * as LibEIP712CoordinatorDomain from '../generated-artifacts/LibEIP712CoordinatorDomain.json';
|
||||||
import * as MixinCoordinatorApprovalVerifier from '../generated-artifacts/MixinCoordinatorApprovalVerifier.json';
|
|
||||||
import * as MixinCoordinatorCore from '../generated-artifacts/MixinCoordinatorCore.json';
|
|
||||||
import * as MixinCoordinatorRegistryCore from '../generated-artifacts/MixinCoordinatorRegistryCore.json';
|
|
||||||
import * as MixinSignatureValidator from '../generated-artifacts/MixinSignatureValidator.json';
|
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
Coordinator: Coordinator as ContractArtifact,
|
Coordinator: Coordinator as ContractArtifact,
|
||||||
MixinCoordinatorApprovalVerifier: MixinCoordinatorApprovalVerifier as ContractArtifact,
|
CoordinatorRegistry: CoordinatorRegistry as ContractArtifact,
|
||||||
MixinCoordinatorCore: MixinCoordinatorCore as ContractArtifact,
|
|
||||||
MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
|
|
||||||
ICoordinatorApprovalVerifier: ICoordinatorApprovalVerifier as ContractArtifact,
|
|
||||||
ICoordinatorCore: ICoordinatorCore as ContractArtifact,
|
|
||||||
ICoordinatorSignatureValidator: ICoordinatorSignatureValidator as ContractArtifact,
|
|
||||||
LibConstants: LibConstants as ContractArtifact,
|
|
||||||
LibCoordinatorApproval: LibCoordinatorApproval as ContractArtifact,
|
LibCoordinatorApproval: LibCoordinatorApproval as ContractArtifact,
|
||||||
LibCoordinatorRichErrors: LibCoordinatorRichErrors as ContractArtifact,
|
LibCoordinatorRichErrors: LibCoordinatorRichErrors as ContractArtifact,
|
||||||
LibEIP712CoordinatorDomain: LibEIP712CoordinatorDomain as ContractArtifact,
|
LibEIP712CoordinatorDomain: LibEIP712CoordinatorDomain as ContractArtifact,
|
||||||
CoordinatorRegistry: CoordinatorRegistry as ContractArtifact,
|
LibConstants: LibConstants as ContractArtifact,
|
||||||
MixinCoordinatorRegistryCore: MixinCoordinatorRegistryCore as ContractArtifact,
|
|
||||||
ICoordinatorRegistryCore: ICoordinatorRegistryCore as ContractArtifact,
|
|
||||||
};
|
};
|
||||||
|
820
contracts/coordinator/src/client/index.ts
Normal file
820
contracts/coordinator/src/client/index.ts
Normal file
@@ -0,0 +1,820 @@
|
|||||||
|
import { SendTransactionOpts } from '@0x/base-contract';
|
||||||
|
import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
|
||||||
|
import { ExchangeContract } from '@0x/contracts-exchange';
|
||||||
|
import { ExchangeFunctionName } from '@0x/contracts-test-utils';
|
||||||
|
import { devConstants } from '@0x/dev-utils';
|
||||||
|
import { schemas } from '@0x/json-schemas';
|
||||||
|
import { generatePseudoRandomSalt, signatureUtils } from '@0x/order-utils';
|
||||||
|
import { Order, SignedOrder, SignedZeroExTransaction, ZeroExTransaction } from '@0x/types';
|
||||||
|
import { BigNumber, fetchAsync } from '@0x/utils';
|
||||||
|
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||||
|
import { CallData, ContractAbi, SupportedProvider, TxData } from 'ethereum-types';
|
||||||
|
import * as HttpStatus from 'http-status-codes';
|
||||||
|
import { flatten } from 'lodash';
|
||||||
|
|
||||||
|
import { artifacts } from '../artifacts';
|
||||||
|
import { CoordinatorContract, CoordinatorRegistryContract } from '../wrappers';
|
||||||
|
|
||||||
|
import { assert } from './utils/assert';
|
||||||
|
import {
|
||||||
|
CoordinatorServerApprovalResponse,
|
||||||
|
CoordinatorServerCancellationResponse,
|
||||||
|
CoordinatorServerError,
|
||||||
|
CoordinatorServerErrorMsg,
|
||||||
|
CoordinatorServerResponse,
|
||||||
|
} from './utils/coordinator_server_types';
|
||||||
|
|
||||||
|
import { decorators } from './utils/decorators';
|
||||||
|
|
||||||
|
export { CoordinatorServerErrorMsg, CoordinatorServerCancellationResponse };
|
||||||
|
|
||||||
|
const DEFAULT_TX_DATA = {
|
||||||
|
gas: devConstants.GAS_LIMIT,
|
||||||
|
gasPrice: new BigNumber(1),
|
||||||
|
value: new BigNumber(150000), // DEFAULT_PROTOCOL_FEE_MULTIPLIER
|
||||||
|
};
|
||||||
|
|
||||||
|
// tx expiration time will be set to (now + default_approval - time_buffer)
|
||||||
|
const DEFAULT_APPROVAL_EXPIRATION_TIME_SECONDS = 90;
|
||||||
|
const DEFAULT_EXPIRATION_TIME_BUFFER_SECONDS = 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class includes all the functionality related to filling or cancelling orders through
|
||||||
|
* the 0x V2 Coordinator extension contract.
|
||||||
|
*/
|
||||||
|
export class CoordinatorClient {
|
||||||
|
public abi: ContractAbi = artifacts.Coordinator.compilerOutput.abi;
|
||||||
|
public chainId: number;
|
||||||
|
public address: string;
|
||||||
|
public exchangeAddress: string;
|
||||||
|
public registryAddress: string;
|
||||||
|
|
||||||
|
private readonly _web3Wrapper: Web3Wrapper;
|
||||||
|
private readonly _contractInstance: CoordinatorContract;
|
||||||
|
private readonly _registryInstance: CoordinatorRegistryContract;
|
||||||
|
private readonly _exchangeInstance: ExchangeContract;
|
||||||
|
private readonly _feeRecipientToEndpoint: { [feeRecipient: string]: string } = {};
|
||||||
|
private readonly _txDefaults: CallData = DEFAULT_TX_DATA;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the 0x transaction has been approved by all of the feeRecipients that correspond to each order in the transaction's Exchange calldata.
|
||||||
|
* Throws an error if the transaction approvals are not valid. Will not detect failures that would occur when the transaction is executed on the Exchange contract.
|
||||||
|
* @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||||
|
* @param txOrigin Required signer of Ethereum transaction calling this function.
|
||||||
|
* @param transactionSignature Proof that the transaction has been signed by the signer.
|
||||||
|
* @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async assertValidCoordinatorApprovalsOrThrowAsync(
|
||||||
|
transaction: ZeroExTransaction,
|
||||||
|
txOrigin: string,
|
||||||
|
transactionSignature: string,
|
||||||
|
approvalSignatures: string[],
|
||||||
|
): Promise<void> {
|
||||||
|
assert.doesConformToSchema('transaction', transaction, schemas.zeroExTransactionSchema);
|
||||||
|
assert.isETHAddressHex('txOrigin', txOrigin);
|
||||||
|
assert.isHexString('transactionSignature', transactionSignature);
|
||||||
|
for (const approvalSignature of approvalSignatures) {
|
||||||
|
assert.isHexString('approvalSignature', approvalSignature);
|
||||||
|
}
|
||||||
|
return this._contractInstance
|
||||||
|
.assertValidCoordinatorApprovals(transaction, txOrigin, transactionSignature, approvalSignatures)
|
||||||
|
.callAsync();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Instantiate CoordinatorClient
|
||||||
|
* @param web3Wrapper Web3Wrapper instance to use.
|
||||||
|
* @param chainId Desired chainId.
|
||||||
|
* @param address The address of the Coordinator contract. If undefined, will
|
||||||
|
* default to the known address corresponding to the chainId.
|
||||||
|
* @param exchangeAddress The address of the Exchange contract. If undefined, will
|
||||||
|
* default to the known address corresponding to the chainId.
|
||||||
|
* @param registryAddress The address of the CoordinatorRegistry contract. If undefined, will
|
||||||
|
* default to the known address corresponding to the chainId.
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
address: string,
|
||||||
|
provider: SupportedProvider,
|
||||||
|
chainId: number,
|
||||||
|
txDefaults?: Partial<TxData>,
|
||||||
|
exchangeAddress?: string,
|
||||||
|
registryAddress?: string,
|
||||||
|
) {
|
||||||
|
this.chainId = chainId;
|
||||||
|
const contractAddresses = getContractAddressesForChainOrThrow(this.chainId);
|
||||||
|
this.address = address === undefined ? contractAddresses.coordinator : address;
|
||||||
|
this.exchangeAddress = exchangeAddress === undefined ? contractAddresses.exchange : exchangeAddress;
|
||||||
|
this.registryAddress = registryAddress === undefined ? contractAddresses.coordinatorRegistry : registryAddress;
|
||||||
|
this._web3Wrapper = new Web3Wrapper(provider);
|
||||||
|
this._txDefaults = { ...txDefaults, ...DEFAULT_TX_DATA };
|
||||||
|
this._contractInstance = new CoordinatorContract(
|
||||||
|
this.address,
|
||||||
|
this._web3Wrapper.getProvider(),
|
||||||
|
this._web3Wrapper.getContractDefaults(),
|
||||||
|
);
|
||||||
|
this._registryInstance = new CoordinatorRegistryContract(
|
||||||
|
this.registryAddress,
|
||||||
|
this._web3Wrapper.getProvider(),
|
||||||
|
this._web3Wrapper.getContractDefaults(),
|
||||||
|
);
|
||||||
|
this._exchangeInstance = new ExchangeContract(
|
||||||
|
this.exchangeAddress,
|
||||||
|
this._web3Wrapper.getProvider(),
|
||||||
|
this._web3Wrapper.getContractDefaults(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills a signed order with an amount denominated in baseUnits of the taker asset. Under-the-hood, this
|
||||||
|
* method uses the `feeRecipientAddress` of the order to look up the coordinator server endpoint registered in the
|
||||||
|
* coordinator registry contract. It requests an approval from that coordinator server before
|
||||||
|
* submitting the order and approval as a 0x transaction to the coordinator extension contract. The coordinator extension
|
||||||
|
* contract validates approvals and then fills the order via the Exchange contract.
|
||||||
|
* @param order An object that conforms to the Order interface.
|
||||||
|
* @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill.
|
||||||
|
* @param signature Signature corresponding to the order.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async fillOrderAsync(
|
||||||
|
order: Order,
|
||||||
|
takerAssetFillAmount: BigNumber,
|
||||||
|
signature: string,
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: Partial<SendTransactionOpts> = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
|
assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
|
||||||
|
return this._executeTxThroughCoordinatorAsync(
|
||||||
|
ExchangeFunctionName.FillOrder,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
[order],
|
||||||
|
order,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signature,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to fill a specific amount of an order. If the entire amount specified cannot be filled,
|
||||||
|
* the fill order is abandoned.
|
||||||
|
* @param order An object that conforms to the Order interface.
|
||||||
|
* @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill.
|
||||||
|
* @param signature Signature corresponding to the order.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async fillOrKillOrderAsync(
|
||||||
|
order: Order,
|
||||||
|
takerAssetFillAmount: BigNumber,
|
||||||
|
signature: string,
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: Partial<SendTransactionOpts> = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
|
assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
|
||||||
|
return this._executeTxThroughCoordinatorAsync(
|
||||||
|
ExchangeFunctionName.FillOrKillOrder,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
[order],
|
||||||
|
order,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signature,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Batch version of fillOrderAsync. Executes multiple fills atomically in a single transaction.
|
||||||
|
* If any `feeRecipientAddress` in the batch is not registered to a coordinator server through the CoordinatorRegistryContract, the whole batch fails.
|
||||||
|
* @param orders An array of orders to fill.
|
||||||
|
* @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
|
||||||
|
* @param signatures Signatures corresponding to the orders.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async batchFillOrdersAsync(
|
||||||
|
orders: Order[],
|
||||||
|
takerAssetFillAmounts: BigNumber[],
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts?: Partial<SendTransactionOpts>,
|
||||||
|
): Promise<string> {
|
||||||
|
return this._batchFillAsync(
|
||||||
|
ExchangeFunctionName.BatchFillOrders,
|
||||||
|
orders,
|
||||||
|
takerAssetFillAmounts,
|
||||||
|
signatures,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* No throw version of batchFillOrdersAsync
|
||||||
|
* @param orders An array of orders to fill.
|
||||||
|
* @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
|
||||||
|
* @param signatures Signatures corresponding to the orders.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async batchFillOrdersNoThrowAsync(
|
||||||
|
orders: Order[],
|
||||||
|
takerAssetFillAmounts: BigNumber[],
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts?: Partial<SendTransactionOpts>,
|
||||||
|
): Promise<string> {
|
||||||
|
return this._batchFillAsync(
|
||||||
|
ExchangeFunctionName.BatchFillOrdersNoThrow,
|
||||||
|
orders,
|
||||||
|
takerAssetFillAmounts,
|
||||||
|
signatures,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Batch version of fillOrKillOrderAsync. Executes multiple fills atomically in a single transaction.
|
||||||
|
* @param orders An array of orders to fill.
|
||||||
|
* @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
|
||||||
|
* @param signatures Signatures corresponding to the orders.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async batchFillOrKillOrdersAsync(
|
||||||
|
orders: Order[],
|
||||||
|
takerAssetFillAmounts: BigNumber[],
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts?: Partial<SendTransactionOpts>,
|
||||||
|
): Promise<string> {
|
||||||
|
return this._batchFillAsync(
|
||||||
|
ExchangeFunctionName.BatchFillOrKillOrders,
|
||||||
|
orders,
|
||||||
|
takerAssetFillAmounts,
|
||||||
|
signatures,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.
|
||||||
|
* If any fill reverts, the error is caught and ignored. Finally, reverts if < makerAssetFillAmount has been bought.
|
||||||
|
* NOTE: This function does not enforce that the makerAsset is the same for each order.
|
||||||
|
* @param orders Array of order specifications.
|
||||||
|
* @param makerAssetFillAmount Desired amount of makerAsset to buy.
|
||||||
|
* @param signatures Proofs that orders have been signed by makers.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async marketBuyOrdersFillOrKillAsync(
|
||||||
|
orders: Order[],
|
||||||
|
makerAssetFillAmount: BigNumber,
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
return this._marketBuySellOrdersAsync(
|
||||||
|
ExchangeFunctionName.MarketBuyOrdersFillOrKill,
|
||||||
|
orders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
signatures,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No throw version of marketBuyOrdersFillOrKillAsync
|
||||||
|
* @param orders An array of orders to fill.
|
||||||
|
* @param makerAssetFillAmount Maker asset fill amount.
|
||||||
|
* @param signatures Signatures corresponding to the orders.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async marketBuyOrdersNoThrowAsync(
|
||||||
|
orders: Order[],
|
||||||
|
makerAssetFillAmount: BigNumber,
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
return this._marketBuySellOrdersAsync(
|
||||||
|
ExchangeFunctionName.MarketBuyOrdersNoThrow,
|
||||||
|
orders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
signatures,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
|
||||||
|
* If any fill reverts, the error is caught and ignored. Finally, reverts if < takerAssetFillAmount has been sold.
|
||||||
|
* NOTE: This function does not enforce that the takerAsset is the same for each order.
|
||||||
|
* @param orders Array of order specifications.
|
||||||
|
* @param takerAssetFillAmount Desired amount of takerAsset to sell.
|
||||||
|
* @param signatures Proofs that orders have been signed by makers.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async marketSellOrdersFillOrKillAsync(
|
||||||
|
orders: Order[],
|
||||||
|
takerAssetFillAmount: BigNumber,
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
return this._marketBuySellOrdersAsync(
|
||||||
|
ExchangeFunctionName.MarketSellOrdersFillOrKill,
|
||||||
|
orders,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signatures,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No throw version of marketSellOrdersAsync
|
||||||
|
* @param orders An array of orders to fill.
|
||||||
|
* @param takerAssetFillAmount Taker asset fill amount.
|
||||||
|
* @param signatures Signatures corresponding to the orders.
|
||||||
|
* @param txData Transaction data. The `from` field should be the user Ethereum address who would like
|
||||||
|
* to fill these orders. Must be available via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async marketSellOrdersNoThrowAsync(
|
||||||
|
orders: Order[],
|
||||||
|
takerAssetFillAmount: BigNumber,
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
return this._marketBuySellOrdersAsync(
|
||||||
|
ExchangeFunctionName.MarketSellOrdersNoThrow,
|
||||||
|
orders,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signatures,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels an order on-chain by submitting an Ethereum transaction.
|
||||||
|
* @param order An object that conforms to the Order interface. The order you would like to cancel.
|
||||||
|
* @param txData Transaction data. The `from` field should be the maker's Ethereum address. Must be available
|
||||||
|
* via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async hardCancelOrderAsync(
|
||||||
|
order: Order,
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
|
return this._executeTxThroughCoordinatorAsync(
|
||||||
|
ExchangeFunctionName.CancelOrder,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
[order],
|
||||||
|
order,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Batch version of hardCancelOrderAsync. Cancels orders on-chain by submitting an Ethereum transaction.
|
||||||
|
* Executes multiple cancels atomically in a single transaction.
|
||||||
|
* @param orders An array of orders to cancel.
|
||||||
|
* @param txData Transaction data. The `from` field should be the maker's Ethereum address. Must be available
|
||||||
|
* via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async batchHardCancelOrdersAsync(
|
||||||
|
orders: Order[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema('orders', orders, schemas.ordersSchema);
|
||||||
|
return this._executeTxThroughCoordinatorAsync(
|
||||||
|
ExchangeFunctionName.BatchCancelOrders,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
orders,
|
||||||
|
orders,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels orders on-chain by submitting an Ethereum transaction.
|
||||||
|
* Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch
|
||||||
|
* and senderAddress equal to coordinator extension contract address.
|
||||||
|
* @param targetOrderEpoch Target order epoch.
|
||||||
|
* @param txData Transaction data. The `from` field should be the maker's Ethereum address. Must be available
|
||||||
|
* via the Provider supplied at instantiation.
|
||||||
|
* @param sendTxOpts Optional arguments for sending the transaction.
|
||||||
|
* @return Transaction hash.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async hardCancelOrdersUpToAsync(
|
||||||
|
targetOrderEpoch: BigNumber,
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
assert.isBigNumber('targetOrderEpoch', targetOrderEpoch);
|
||||||
|
return this._executeTxThroughCoordinatorAsync(
|
||||||
|
ExchangeFunctionName.CancelOrdersUpTo,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
[],
|
||||||
|
targetOrderEpoch,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Soft cancel a given order.
|
||||||
|
* Soft cancels are recorded only on coordinator operator servers and do not involve an Ethereum transaction.
|
||||||
|
* See [soft cancels](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#soft-cancels).
|
||||||
|
* @param order An object that conforms to the Order or SignedOrder interface. The order you would like to cancel.
|
||||||
|
* @return CoordinatorServerCancellationResponse. See [Cancellation Response](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#response).
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async softCancelAsync(order: Order): Promise<CoordinatorServerCancellationResponse> {
|
||||||
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
|
assert.isETHAddressHex('feeRecipientAddress', order.feeRecipientAddress);
|
||||||
|
assert.isSenderAddressAsync('makerAddress', order.makerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
|
const data = this._exchangeInstance.cancelOrder(order).getABIEncodedTransactionData();
|
||||||
|
const transaction = await this._generateSignedZeroExTransactionAsync(data, order.makerAddress);
|
||||||
|
const endpoint = await this._getServerEndpointOrThrowAsync(order);
|
||||||
|
|
||||||
|
const response = await this._executeServerRequestAsync(transaction, order.makerAddress, endpoint);
|
||||||
|
if (response.isError) {
|
||||||
|
const approvedOrders = new Array();
|
||||||
|
const cancellations = new Array();
|
||||||
|
const errors = [
|
||||||
|
{
|
||||||
|
...response,
|
||||||
|
orders: [order],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
throw new CoordinatorServerError(
|
||||||
|
CoordinatorServerErrorMsg.CancellationFailed,
|
||||||
|
approvedOrders,
|
||||||
|
cancellations,
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return response.body as CoordinatorServerCancellationResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Batch version of softCancelOrderAsync. Requests multiple soft cancels
|
||||||
|
* @param orders An array of orders to cancel.
|
||||||
|
* @return CoordinatorServerCancellationResponse. See [Cancellation Response](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/coordinator-specification.md#response).
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async batchSoftCancelAsync(orders: SignedOrder[]): Promise<CoordinatorServerCancellationResponse[]> {
|
||||||
|
assert.doesConformToSchema('orders', orders, schemas.ordersSchema);
|
||||||
|
const makerAddress = getMakerAddressOrThrow(orders);
|
||||||
|
assert.isSenderAddressAsync('makerAddress', makerAddress, this._web3Wrapper);
|
||||||
|
const data = this._exchangeInstance.batchCancelOrders(orders).getABIEncodedTransactionData();
|
||||||
|
const transaction = await this._generateSignedZeroExTransactionAsync(data, makerAddress);
|
||||||
|
|
||||||
|
// make server requests
|
||||||
|
const errorResponses: CoordinatorServerResponse[] = [];
|
||||||
|
const successResponses: CoordinatorServerCancellationResponse[] = [];
|
||||||
|
const serverEndpointsToOrders = await this._mapServerEndpointsToOrdersAsync(orders);
|
||||||
|
for (const endpoint of Object.keys(serverEndpointsToOrders)) {
|
||||||
|
const response = await this._executeServerRequestAsync(transaction, makerAddress, endpoint);
|
||||||
|
if (response.isError) {
|
||||||
|
errorResponses.push(response);
|
||||||
|
} else {
|
||||||
|
successResponses.push(response.body as CoordinatorServerCancellationResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no errors
|
||||||
|
if (errorResponses.length === 0) {
|
||||||
|
return successResponses;
|
||||||
|
} else {
|
||||||
|
// lookup orders with errors
|
||||||
|
const errorsWithOrders = errorResponses.map(resp => {
|
||||||
|
const endpoint = resp.coordinatorOperator;
|
||||||
|
const _orders = serverEndpointsToOrders[endpoint];
|
||||||
|
return {
|
||||||
|
...resp,
|
||||||
|
orders: _orders,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const approvedOrders = new Array();
|
||||||
|
const cancellations = successResponses;
|
||||||
|
// return errors and approvals
|
||||||
|
throw new CoordinatorServerError(
|
||||||
|
CoordinatorServerErrorMsg.CancellationFailed,
|
||||||
|
approvedOrders,
|
||||||
|
cancellations,
|
||||||
|
errorsWithOrders,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recovers the address of a signer given a hash and signature.
|
||||||
|
* @param hash Any 32 byte hash.
|
||||||
|
* @param signature Proof that the hash has been signed by signer.
|
||||||
|
* @returns Signer address.
|
||||||
|
*/
|
||||||
|
@decorators.asyncZeroExErrorHandler
|
||||||
|
public async getSignerAddressAsync(hash: string, signature: string): Promise<string> {
|
||||||
|
assert.isHexString('hash', hash);
|
||||||
|
assert.isHexString('signature', signature);
|
||||||
|
const signerAddress = await this._contractInstance.getSignerAddress(hash, signature).callAsync();
|
||||||
|
return signerAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _marketBuySellOrdersAsync(
|
||||||
|
exchangeFn: ExchangeFunctionName,
|
||||||
|
orders: Order[],
|
||||||
|
assetFillAmount: BigNumber,
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema('orders', orders, schemas.ordersSchema);
|
||||||
|
assert.isBigNumber('assetFillAmount', assetFillAmount);
|
||||||
|
return this._executeTxThroughCoordinatorAsync(
|
||||||
|
exchangeFn,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
orders,
|
||||||
|
orders,
|
||||||
|
assetFillAmount,
|
||||||
|
signatures,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _batchFillAsync(
|
||||||
|
exchangeFn: ExchangeFunctionName,
|
||||||
|
orders: Order[],
|
||||||
|
takerAssetFillAmounts: BigNumber[],
|
||||||
|
signatures: string[],
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: SendTransactionOpts = { shouldValidate: true },
|
||||||
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema('orders', orders, schemas.ordersSchema);
|
||||||
|
takerAssetFillAmounts.forEach(takerAssetFillAmount =>
|
||||||
|
assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount),
|
||||||
|
);
|
||||||
|
return this._executeTxThroughCoordinatorAsync(
|
||||||
|
exchangeFn,
|
||||||
|
txData,
|
||||||
|
sendTxOpts,
|
||||||
|
orders,
|
||||||
|
orders,
|
||||||
|
takerAssetFillAmounts,
|
||||||
|
signatures,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _executeTxThroughCoordinatorAsync(
|
||||||
|
exchangeFn: ExchangeFunctionName,
|
||||||
|
txData: TxData,
|
||||||
|
sendTxOpts: Partial<SendTransactionOpts>,
|
||||||
|
ordersNeedingApprovals: Order[],
|
||||||
|
...args: any[] // tslint:disable-line:trailing-comma
|
||||||
|
): Promise<string> {
|
||||||
|
assert.isETHAddressHex('takerAddress', txData.from);
|
||||||
|
await assert.isSenderAddressAsync('takerAddress', txData.from, this._web3Wrapper);
|
||||||
|
|
||||||
|
// get ABI encoded transaction data for the desired exchange method
|
||||||
|
const data = (this._exchangeInstance as any)[exchangeFn](...args).getABIEncodedTransactionData();
|
||||||
|
|
||||||
|
// generate and sign a ZeroExTransaction
|
||||||
|
const signedZrxTx = await this._generateSignedZeroExTransactionAsync(data, txData.from, txData.gasPrice);
|
||||||
|
|
||||||
|
// get approval signatures from registered coordinator operators
|
||||||
|
const approvalSignatures = await this._getApprovalsAsync(signedZrxTx, ordersNeedingApprovals, txData.from);
|
||||||
|
|
||||||
|
// execute the transaction through the Coordinator Contract
|
||||||
|
const txDataWithDefaults = {
|
||||||
|
...this._txDefaults,
|
||||||
|
...txData, // override defaults
|
||||||
|
};
|
||||||
|
const txHash = this._contractInstance
|
||||||
|
.executeTransaction(signedZrxTx, txData.from, signedZrxTx.signature, approvalSignatures)
|
||||||
|
.sendTransactionAsync(txDataWithDefaults, sendTxOpts);
|
||||||
|
return txHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _generateSignedZeroExTransactionAsync(
|
||||||
|
data: string,
|
||||||
|
signerAddress: string,
|
||||||
|
gasPrice?: BigNumber | string | number,
|
||||||
|
): Promise<SignedZeroExTransaction> {
|
||||||
|
const transaction: ZeroExTransaction = {
|
||||||
|
salt: generatePseudoRandomSalt(),
|
||||||
|
signerAddress,
|
||||||
|
data,
|
||||||
|
domain: {
|
||||||
|
verifyingContract: this.exchangeAddress,
|
||||||
|
chainId: await this._web3Wrapper.getChainIdAsync(),
|
||||||
|
},
|
||||||
|
expirationTimeSeconds: new BigNumber(
|
||||||
|
Math.floor(Date.now() / 1000) +
|
||||||
|
DEFAULT_APPROVAL_EXPIRATION_TIME_SECONDS -
|
||||||
|
DEFAULT_EXPIRATION_TIME_BUFFER_SECONDS,
|
||||||
|
),
|
||||||
|
gasPrice: gasPrice ? new BigNumber(gasPrice) : new BigNumber(1),
|
||||||
|
};
|
||||||
|
const signedZrxTx = await signatureUtils.ecSignTransactionAsync(
|
||||||
|
this._web3Wrapper.getProvider(),
|
||||||
|
transaction,
|
||||||
|
transaction.signerAddress,
|
||||||
|
);
|
||||||
|
return signedZrxTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _getApprovalsAsync(
|
||||||
|
transaction: SignedZeroExTransaction,
|
||||||
|
orders: Order[],
|
||||||
|
txOrigin: string,
|
||||||
|
): Promise<string[]> {
|
||||||
|
const coordinatorOrders = orders.filter(o => o.senderAddress === this.address);
|
||||||
|
if (coordinatorOrders.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const serverEndpointsToOrders = await this._mapServerEndpointsToOrdersAsync(coordinatorOrders);
|
||||||
|
|
||||||
|
// make server requests
|
||||||
|
const errorResponses: CoordinatorServerResponse[] = [];
|
||||||
|
const approvalResponses: CoordinatorServerResponse[] = [];
|
||||||
|
for (const endpoint of Object.keys(serverEndpointsToOrders)) {
|
||||||
|
const response = await this._executeServerRequestAsync(transaction, txOrigin, endpoint);
|
||||||
|
if (response.isError) {
|
||||||
|
errorResponses.push(response);
|
||||||
|
} else {
|
||||||
|
approvalResponses.push(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no errors
|
||||||
|
if (errorResponses.length === 0) {
|
||||||
|
// concatenate all approval responses
|
||||||
|
return approvalResponses.reduce(
|
||||||
|
(accumulator, response) =>
|
||||||
|
accumulator.concat((response.body as CoordinatorServerApprovalResponse).signatures),
|
||||||
|
[] as string[],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// format errors and approvals
|
||||||
|
// concatenate approvals
|
||||||
|
const notCoordinatorOrders = orders.filter(o => o.senderAddress !== this.address);
|
||||||
|
const approvedOrdersNested = approvalResponses.map(resp => {
|
||||||
|
const endpoint = resp.coordinatorOperator;
|
||||||
|
return serverEndpointsToOrders[endpoint];
|
||||||
|
});
|
||||||
|
const approvedOrders = flatten(approvedOrdersNested.concat(notCoordinatorOrders));
|
||||||
|
|
||||||
|
// lookup orders with errors
|
||||||
|
const errorsWithOrders = errorResponses.map(resp => {
|
||||||
|
const endpoint = resp.coordinatorOperator;
|
||||||
|
return {
|
||||||
|
...resp,
|
||||||
|
orders: serverEndpointsToOrders[endpoint],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// throw informative error
|
||||||
|
const cancellations = new Array();
|
||||||
|
throw new CoordinatorServerError(
|
||||||
|
CoordinatorServerErrorMsg.FillFailed,
|
||||||
|
approvedOrders,
|
||||||
|
cancellations,
|
||||||
|
errorsWithOrders,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _getServerEndpointOrThrowAsync(order: Order): Promise<string> {
|
||||||
|
const cached = this._feeRecipientToEndpoint[order.feeRecipientAddress];
|
||||||
|
const endpoint =
|
||||||
|
cached !== undefined
|
||||||
|
? cached
|
||||||
|
: await _fetchServerEndpointOrThrowAsync(order.feeRecipientAddress, this._registryInstance);
|
||||||
|
return endpoint;
|
||||||
|
|
||||||
|
async function _fetchServerEndpointOrThrowAsync(
|
||||||
|
feeRecipient: string,
|
||||||
|
registryInstance: CoordinatorRegistryContract,
|
||||||
|
): Promise<string> {
|
||||||
|
const coordinatorOperatorEndpoint = await registryInstance.getCoordinatorEndpoint(feeRecipient).callAsync();
|
||||||
|
if (coordinatorOperatorEndpoint === '' || coordinatorOperatorEndpoint === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
`No Coordinator server endpoint found in Coordinator Registry for feeRecipientAddress: ${feeRecipient}. Registry contract address: [${
|
||||||
|
registryInstance.address
|
||||||
|
}] Order: [${JSON.stringify(order)}]`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return coordinatorOperatorEndpoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _executeServerRequestAsync(
|
||||||
|
signedTransaction: SignedZeroExTransaction,
|
||||||
|
txOrigin: string,
|
||||||
|
endpoint: string,
|
||||||
|
): Promise<CoordinatorServerResponse> {
|
||||||
|
const requestPayload = {
|
||||||
|
signedTransaction,
|
||||||
|
txOrigin,
|
||||||
|
};
|
||||||
|
const response = await fetchAsync(`${endpoint}/v2/request_transaction?chainId=${this.chainId}`, {
|
||||||
|
body: JSON.stringify(requestPayload),
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const isError = response.status !== HttpStatus.OK;
|
||||||
|
const isValidationError = response.status === HttpStatus.BAD_REQUEST;
|
||||||
|
const json = isError && !isValidationError ? undefined : await response.json();
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
isError,
|
||||||
|
status: response.status,
|
||||||
|
body: isError ? undefined : json,
|
||||||
|
error: isError ? json : undefined,
|
||||||
|
request: requestPayload,
|
||||||
|
coordinatorOperator: endpoint,
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _mapServerEndpointsToOrdersAsync(
|
||||||
|
coordinatorOrders: Order[],
|
||||||
|
): Promise<{ [endpoint: string]: Order[] }> {
|
||||||
|
const groupByFeeRecipient: { [feeRecipient: string]: Order[] } = {};
|
||||||
|
for (const order of coordinatorOrders) {
|
||||||
|
const feeRecipient = order.feeRecipientAddress;
|
||||||
|
if (groupByFeeRecipient[feeRecipient] === undefined) {
|
||||||
|
groupByFeeRecipient[feeRecipient] = [] as Order[];
|
||||||
|
}
|
||||||
|
groupByFeeRecipient[feeRecipient].push(order);
|
||||||
|
}
|
||||||
|
const serverEndpointsToOrders: { [endpoint: string]: Order[] } = {};
|
||||||
|
for (const orders of Object.values(groupByFeeRecipient)) {
|
||||||
|
const endpoint = await this._getServerEndpointOrThrowAsync(orders[0]);
|
||||||
|
if (serverEndpointsToOrders[endpoint] === undefined) {
|
||||||
|
serverEndpointsToOrders[endpoint] = [];
|
||||||
|
}
|
||||||
|
serverEndpointsToOrders[endpoint] = serverEndpointsToOrders[endpoint].concat(orders);
|
||||||
|
}
|
||||||
|
return serverEndpointsToOrders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMakerAddressOrThrow(orders: Array<Order | SignedOrder>): string {
|
||||||
|
const uniqueMakerAddresses = new Set(orders.map(o => o.makerAddress));
|
||||||
|
if (uniqueMakerAddresses.size > 1) {
|
||||||
|
throw new Error(`All orders in a batch must have the same makerAddress`);
|
||||||
|
}
|
||||||
|
return orders[0].makerAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable:max-file-line-count
|
@@ -4,7 +4,6 @@ import { Schema } from '@0x/json-schemas'; // tslint:disable-line:no-unused-vari
|
|||||||
import { Order } from '@0x/types'; // tslint:disable-line:no-unused-variable
|
import { Order } from '@0x/types'; // tslint:disable-line:no-unused-variable
|
||||||
import { BigNumber } from '@0x/utils'; // tslint:disable-line:no-unused-variable
|
import { BigNumber } from '@0x/utils'; // tslint:disable-line:no-unused-variable
|
||||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
|
||||||
|
|
||||||
export const assert = {
|
export const assert = {
|
||||||
...sharedAssert,
|
...sharedAssert,
|
@@ -2,10 +2,6 @@ import { Order, SignedOrder, SignedZeroExTransaction } from '@0x/types';
|
|||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
|
|
||||||
export interface CoordinatorServerApprovalResponse {
|
export interface CoordinatorServerApprovalResponse {
|
||||||
signatures: string[];
|
|
||||||
expirationTimeSeconds: BigNumber[];
|
|
||||||
}
|
|
||||||
export interface CoordinatorServerApprovalRawResponse {
|
|
||||||
signatures: string[];
|
signatures: string[];
|
||||||
expirationTimeSeconds: BigNumber;
|
expirationTimeSeconds: BigNumber;
|
||||||
}
|
}
|
||||||
@@ -24,7 +20,7 @@ export interface CoordinatorOutstandingFillSignatures {
|
|||||||
export interface CoordinatorServerResponse {
|
export interface CoordinatorServerResponse {
|
||||||
isError: boolean;
|
isError: boolean;
|
||||||
status: number;
|
status: number;
|
||||||
body?: CoordinatorServerCancellationResponse | CoordinatorServerApprovalRawResponse;
|
body?: CoordinatorServerCancellationResponse | CoordinatorServerApprovalResponse;
|
||||||
error?: any;
|
error?: any;
|
||||||
request: CoordinatorServerRequest;
|
request: CoordinatorServerRequest;
|
||||||
coordinatorOperator: string;
|
coordinatorOperator: string;
|
||||||
@@ -38,12 +34,12 @@ export interface CoordinatorServerRequest {
|
|||||||
|
|
||||||
export class CoordinatorServerError extends Error {
|
export class CoordinatorServerError extends Error {
|
||||||
public message: CoordinatorServerErrorMsg;
|
public message: CoordinatorServerErrorMsg;
|
||||||
public approvedOrders?: SignedOrder[] = [];
|
public approvedOrders?: Order[] = [];
|
||||||
public cancellations?: CoordinatorServerCancellationResponse[] = [];
|
public cancellations?: CoordinatorServerCancellationResponse[] = [];
|
||||||
public errors: CoordinatorServerResponse[];
|
public errors: CoordinatorServerResponse[];
|
||||||
constructor(
|
constructor(
|
||||||
message: CoordinatorServerErrorMsg,
|
message: CoordinatorServerErrorMsg,
|
||||||
approvedOrders: SignedOrder[],
|
approvedOrders: Order[],
|
||||||
cancellations: CoordinatorServerCancellationResponse[],
|
cancellations: CoordinatorServerCancellationResponse[],
|
||||||
errors: CoordinatorServerResponse[],
|
errors: CoordinatorServerResponse[],
|
||||||
) {
|
) {
|
29
contracts/coordinator/src/hash_utils.ts
Normal file
29
contracts/coordinator/src/hash_utils.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { eip712Utils } from '@0x/order-utils';
|
||||||
|
import { SignedZeroExTransaction } from '@0x/types';
|
||||||
|
import { hexUtils, signTypedDataUtils } from '@0x/utils';
|
||||||
|
|
||||||
|
export const hashUtils = {
|
||||||
|
async getApprovalHashBufferAsync(
|
||||||
|
transaction: SignedZeroExTransaction,
|
||||||
|
verifyingContract: string,
|
||||||
|
txOrigin: string,
|
||||||
|
): Promise<Buffer> {
|
||||||
|
const typedData = await eip712Utils.createCoordinatorApprovalTypedDataAsync(
|
||||||
|
transaction,
|
||||||
|
verifyingContract,
|
||||||
|
txOrigin,
|
||||||
|
);
|
||||||
|
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
|
||||||
|
return hashBuffer;
|
||||||
|
},
|
||||||
|
async getApprovalHashHexAsync(
|
||||||
|
transaction: SignedZeroExTransaction,
|
||||||
|
verifyingContract: string,
|
||||||
|
txOrigin: string,
|
||||||
|
): Promise<string> {
|
||||||
|
const hashHex = hexUtils.concat(
|
||||||
|
await hashUtils.getApprovalHashBufferAsync(transaction, verifyingContract, txOrigin),
|
||||||
|
);
|
||||||
|
return hashHex;
|
||||||
|
},
|
||||||
|
};
|
@@ -1,3 +1,66 @@
|
|||||||
export * from './artifacts';
|
export { artifacts } from './artifacts';
|
||||||
export * from './wrappers';
|
export {
|
||||||
export * from '../test/utils';
|
CoordinatorContract,
|
||||||
|
CoordinatorRegistryContract,
|
||||||
|
LibConstantsContract,
|
||||||
|
LibCoordinatorApprovalContract,
|
||||||
|
LibCoordinatorRichErrorsContract,
|
||||||
|
LibEIP712CoordinatorDomainContract,
|
||||||
|
} from './wrappers';
|
||||||
|
export { CoordinatorRevertErrors } from '@0x/utils';
|
||||||
|
export { CoordinatorServerCancellationResponse } from './client/index';
|
||||||
|
export { ApprovalFactory } from './approval_factory';
|
||||||
|
export { SignedCoordinatorApproval } from './types';
|
||||||
|
export {
|
||||||
|
Order,
|
||||||
|
SignedOrder,
|
||||||
|
SignatureType,
|
||||||
|
SignedZeroExTransaction,
|
||||||
|
EIP712DomainWithDefaultSchema,
|
||||||
|
ZeroExTransaction,
|
||||||
|
} from '@0x/types';
|
||||||
|
export { AwaitTransactionSuccessOpts, SendTransactionOpts } from '@0x/base-contract';
|
||||||
|
export {
|
||||||
|
ContractArtifact,
|
||||||
|
ContractChains,
|
||||||
|
CompilerOpts,
|
||||||
|
StandardContractOutput,
|
||||||
|
CompilerSettings,
|
||||||
|
ContractChainData,
|
||||||
|
ContractAbi,
|
||||||
|
DevdocOutput,
|
||||||
|
EvmOutput,
|
||||||
|
CompilerSettingsMetadata,
|
||||||
|
OptimizerSettings,
|
||||||
|
OutputField,
|
||||||
|
ParamDescription,
|
||||||
|
EvmBytecodeOutput,
|
||||||
|
AbiDefinition,
|
||||||
|
FunctionAbi,
|
||||||
|
EventAbi,
|
||||||
|
RevertErrorAbi,
|
||||||
|
EventParameter,
|
||||||
|
DataItem,
|
||||||
|
MethodAbi,
|
||||||
|
ConstructorAbi,
|
||||||
|
FallbackAbi,
|
||||||
|
ConstructorStateMutability,
|
||||||
|
TupleDataItem,
|
||||||
|
StateMutability,
|
||||||
|
SupportedProvider,
|
||||||
|
TxData,
|
||||||
|
TxDataPayable,
|
||||||
|
Web3JsProvider,
|
||||||
|
GanacheProvider,
|
||||||
|
EIP1193Provider,
|
||||||
|
ZeroExProvider,
|
||||||
|
EIP1193Event,
|
||||||
|
JSONRPCRequestPayload,
|
||||||
|
JSONRPCErrorCallback,
|
||||||
|
Web3JsV1Provider,
|
||||||
|
Web3JsV2Provider,
|
||||||
|
Web3JsV3Provider,
|
||||||
|
JSONRPCResponsePayload,
|
||||||
|
JSONRPCResponseError,
|
||||||
|
} from 'ethereum-types';
|
||||||
|
export { CoordinatorClient, CoordinatorServerErrorMsg } from './client/index';
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { SignedZeroExTransaction } from '@0x/types';
|
import { SignedZeroExTransaction } from '@0x/types';
|
||||||
|
import { BigNumber } from '@0x/utils';
|
||||||
|
|
||||||
export interface CoordinatorApproval {
|
export interface CoordinatorApproval {
|
||||||
transaction: SignedZeroExTransaction;
|
transaction: SignedZeroExTransaction;
|
||||||
@@ -8,3 +9,9 @@ export interface CoordinatorApproval {
|
|||||||
export interface SignedCoordinatorApproval extends CoordinatorApproval {
|
export interface SignedCoordinatorApproval extends CoordinatorApproval {
|
||||||
signature: string;
|
signature: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CoordinatorTransaction {
|
||||||
|
salt: BigNumber;
|
||||||
|
signerAddress: string;
|
||||||
|
data: string;
|
||||||
|
}
|
@@ -5,15 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
export * from '../generated-wrappers/coordinator';
|
export * from '../generated-wrappers/coordinator';
|
||||||
export * from '../generated-wrappers/coordinator_registry';
|
export * from '../generated-wrappers/coordinator_registry';
|
||||||
export * from '../generated-wrappers/i_coordinator_approval_verifier';
|
|
||||||
export * from '../generated-wrappers/i_coordinator_core';
|
|
||||||
export * from '../generated-wrappers/i_coordinator_registry_core';
|
|
||||||
export * from '../generated-wrappers/i_coordinator_signature_validator';
|
|
||||||
export * from '../generated-wrappers/lib_constants';
|
export * from '../generated-wrappers/lib_constants';
|
||||||
export * from '../generated-wrappers/lib_coordinator_approval';
|
export * from '../generated-wrappers/lib_coordinator_approval';
|
||||||
export * from '../generated-wrappers/lib_coordinator_rich_errors';
|
export * from '../generated-wrappers/lib_coordinator_rich_errors';
|
||||||
export * from '../generated-wrappers/lib_e_i_p712_coordinator_domain';
|
export * from '../generated-wrappers/lib_e_i_p712_coordinator_domain';
|
||||||
export * from '../generated-wrappers/mixin_coordinator_approval_verifier';
|
|
||||||
export * from '../generated-wrappers/mixin_coordinator_core';
|
|
||||||
export * from '../generated-wrappers/mixin_coordinator_registry_core';
|
|
||||||
export * from '../generated-wrappers/mixin_signature_validator';
|
|
||||||
|
37
contracts/coordinator/test/artifacts.ts
Normal file
37
contracts/coordinator/test/artifacts.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
import { ContractArtifact } from 'ethereum-types';
|
||||||
|
|
||||||
|
import * as Coordinator from '../test/generated-artifacts/Coordinator.json';
|
||||||
|
import * as CoordinatorRegistry from '../test/generated-artifacts/CoordinatorRegistry.json';
|
||||||
|
import * as ICoordinatorApprovalVerifier from '../test/generated-artifacts/ICoordinatorApprovalVerifier.json';
|
||||||
|
import * as ICoordinatorCore from '../test/generated-artifacts/ICoordinatorCore.json';
|
||||||
|
import * as ICoordinatorRegistryCore from '../test/generated-artifacts/ICoordinatorRegistryCore.json';
|
||||||
|
import * as ICoordinatorSignatureValidator from '../test/generated-artifacts/ICoordinatorSignatureValidator.json';
|
||||||
|
import * as LibConstants from '../test/generated-artifacts/LibConstants.json';
|
||||||
|
import * as LibCoordinatorApproval from '../test/generated-artifacts/LibCoordinatorApproval.json';
|
||||||
|
import * as LibCoordinatorRichErrors from '../test/generated-artifacts/LibCoordinatorRichErrors.json';
|
||||||
|
import * as LibEIP712CoordinatorDomain from '../test/generated-artifacts/LibEIP712CoordinatorDomain.json';
|
||||||
|
import * as MixinCoordinatorApprovalVerifier from '../test/generated-artifacts/MixinCoordinatorApprovalVerifier.json';
|
||||||
|
import * as MixinCoordinatorCore from '../test/generated-artifacts/MixinCoordinatorCore.json';
|
||||||
|
import * as MixinCoordinatorRegistryCore from '../test/generated-artifacts/MixinCoordinatorRegistryCore.json';
|
||||||
|
import * as MixinSignatureValidator from '../test/generated-artifacts/MixinSignatureValidator.json';
|
||||||
|
export const artifacts = {
|
||||||
|
Coordinator: Coordinator as ContractArtifact,
|
||||||
|
MixinCoordinatorApprovalVerifier: MixinCoordinatorApprovalVerifier as ContractArtifact,
|
||||||
|
MixinCoordinatorCore: MixinCoordinatorCore as ContractArtifact,
|
||||||
|
MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
|
||||||
|
ICoordinatorApprovalVerifier: ICoordinatorApprovalVerifier as ContractArtifact,
|
||||||
|
ICoordinatorCore: ICoordinatorCore as ContractArtifact,
|
||||||
|
ICoordinatorSignatureValidator: ICoordinatorSignatureValidator as ContractArtifact,
|
||||||
|
LibConstants: LibConstants as ContractArtifact,
|
||||||
|
LibCoordinatorApproval: LibCoordinatorApproval as ContractArtifact,
|
||||||
|
LibCoordinatorRichErrors: LibCoordinatorRichErrors as ContractArtifact,
|
||||||
|
LibEIP712CoordinatorDomain: LibEIP712CoordinatorDomain as ContractArtifact,
|
||||||
|
CoordinatorRegistry: CoordinatorRegistry as ContractArtifact,
|
||||||
|
MixinCoordinatorRegistryCore: MixinCoordinatorRegistryCore as ContractArtifact,
|
||||||
|
ICoordinatorRegistryCore: ICoordinatorRegistryCore as ContractArtifact,
|
||||||
|
};
|
@@ -1,6 +1,8 @@
|
|||||||
import { blockchainTests, expect, verifyEvents } from '@0x/contracts-test-utils';
|
import { blockchainTests, expect, verifyEvents } from '@0x/contracts-test-utils';
|
||||||
|
|
||||||
import { artifacts, CoordinatorRegistryContract, CoordinatorRegistryCoordinatorEndpointSetEventArgs } from '../src';
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { CoordinatorRegistryContract, CoordinatorRegistryCoordinatorEndpointSetEventArgs } from './wrappers';
|
||||||
|
|
||||||
// tslint:disable:no-unnecessary-type-assertion
|
// tslint:disable:no-unnecessary-type-assertion
|
||||||
blockchainTests.resets('Coordinator Registry tests', env => {
|
blockchainTests.resets('Coordinator Registry tests', env => {
|
||||||
@@ -23,43 +25,42 @@ blockchainTests.resets('Coordinator Registry tests', env => {
|
|||||||
});
|
});
|
||||||
describe('core', () => {
|
describe('core', () => {
|
||||||
it('Should successfully set a Coordinator endpoint', async () => {
|
it('Should successfully set a Coordinator endpoint', async () => {
|
||||||
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, {
|
await coordinatorRegistry.setCoordinatorEndpoint(coordinatorEndpoint).awaitTransactionSuccessAsync({
|
||||||
from: coordinatorOperator,
|
from: coordinatorOperator,
|
||||||
});
|
});
|
||||||
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
|
const recordedCoordinatorEndpoint = await coordinatorRegistry
|
||||||
coordinatorOperator,
|
.getCoordinatorEndpoint(coordinatorOperator)
|
||||||
);
|
.callAsync();
|
||||||
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
||||||
});
|
});
|
||||||
it('Should successfully unset a Coordinator endpoint', async () => {
|
it('Should successfully unset a Coordinator endpoint', async () => {
|
||||||
// set Coordinator endpoint
|
// set Coordinator endpoint
|
||||||
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, {
|
await coordinatorRegistry.setCoordinatorEndpoint(coordinatorEndpoint).awaitTransactionSuccessAsync({
|
||||||
from: coordinatorOperator,
|
from: coordinatorOperator,
|
||||||
});
|
});
|
||||||
let recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
|
let recordedCoordinatorEndpoint = await coordinatorRegistry
|
||||||
coordinatorOperator,
|
.getCoordinatorEndpoint(coordinatorOperator)
|
||||||
);
|
.callAsync();
|
||||||
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
||||||
// unset Coordinator endpoint
|
// unset Coordinator endpoint
|
||||||
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(nilCoordinatorEndpoint, {
|
await coordinatorRegistry.setCoordinatorEndpoint(nilCoordinatorEndpoint).awaitTransactionSuccessAsync({
|
||||||
from: coordinatorOperator,
|
from: coordinatorOperator,
|
||||||
});
|
});
|
||||||
recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
|
recordedCoordinatorEndpoint = await coordinatorRegistry
|
||||||
coordinatorOperator,
|
.getCoordinatorEndpoint(coordinatorOperator)
|
||||||
);
|
.callAsync();
|
||||||
expect(recordedCoordinatorEndpoint).to.be.equal(nilCoordinatorEndpoint);
|
expect(recordedCoordinatorEndpoint).to.be.equal(nilCoordinatorEndpoint);
|
||||||
});
|
});
|
||||||
it('Should emit an event when setting Coordinator endpoint', async () => {
|
it('Should emit an event when setting Coordinator endpoint', async () => {
|
||||||
// set Coordinator endpoint
|
// set Coordinator endpoint
|
||||||
const txReceipt = await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(
|
const txReceipt = await coordinatorRegistry
|
||||||
coordinatorEndpoint,
|
.setCoordinatorEndpoint(coordinatorEndpoint)
|
||||||
{
|
.awaitTransactionSuccessAsync({
|
||||||
from: coordinatorOperator,
|
from: coordinatorOperator,
|
||||||
},
|
});
|
||||||
);
|
const recordedCoordinatorEndpoint = await coordinatorRegistry
|
||||||
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
|
.getCoordinatorEndpoint(coordinatorOperator)
|
||||||
coordinatorOperator,
|
.callAsync();
|
||||||
);
|
|
||||||
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
||||||
// validate event
|
// validate event
|
||||||
const expectedEvent: CoordinatorRegistryCoordinatorEndpointSetEventArgs = {
|
const expectedEvent: CoordinatorRegistryCoordinatorEndpointSetEventArgs = {
|
||||||
|
@@ -1,8 +1,11 @@
|
|||||||
import { blockchainTests, constants, expect, randomAddress } from '@0x/contracts-test-utils';
|
import { blockchainTests, constants, expect, randomAddress, transactionHashUtils } from '@0x/contracts-test-utils';
|
||||||
import { transactionHashUtils } from '@0x/order-utils';
|
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
|
|
||||||
import { artifacts, CoordinatorContract, hashUtils } from '../src';
|
import { hashUtils } from '../src/hash_utils';
|
||||||
|
|
||||||
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { CoordinatorContract } from './wrappers';
|
||||||
|
|
||||||
blockchainTests.resets('Libs tests', env => {
|
blockchainTests.resets('Libs tests', env => {
|
||||||
let coordinatorContract: CoordinatorContract;
|
let coordinatorContract: CoordinatorContract;
|
||||||
@@ -41,8 +44,12 @@ blockchainTests.resets('Libs tests', env => {
|
|||||||
transactionHash: transactionHashUtils.getTransactionHashHex(signedTx),
|
transactionHash: transactionHashUtils.getTransactionHashHex(signedTx),
|
||||||
transactionSignature: signedTx.signature,
|
transactionSignature: signedTx.signature,
|
||||||
};
|
};
|
||||||
const expectedApprovalHash = hashUtils.getApprovalHashHex(signedTx, coordinatorContract.address, txOrigin);
|
const expectedApprovalHash = await hashUtils.getApprovalHashHexAsync(
|
||||||
const approvalHash = await coordinatorContract.getCoordinatorApprovalHash.callAsync(approval);
|
signedTx,
|
||||||
|
coordinatorContract.address,
|
||||||
|
txOrigin,
|
||||||
|
);
|
||||||
|
const approvalHash = await coordinatorContract.getCoordinatorApprovalHash(approval).callAsync();
|
||||||
expect(expectedApprovalHash).to.eq(approvalHash);
|
expect(expectedApprovalHash).to.eq(approvalHash);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,18 +1,22 @@
|
|||||||
import { constants as exchangeConstants, exchangeDataEncoder, ExchangeFunctionName } from '@0x/contracts-exchange';
|
import { exchangeDataEncoder } from '@0x/contracts-exchange';
|
||||||
import {
|
import {
|
||||||
blockchainTests,
|
blockchainTests,
|
||||||
constants,
|
constants,
|
||||||
|
ExchangeFunctionName,
|
||||||
expect,
|
expect,
|
||||||
hexConcat,
|
|
||||||
hexSlice,
|
|
||||||
randomAddress,
|
randomAddress,
|
||||||
TransactionFactory,
|
TransactionFactory,
|
||||||
|
transactionHashUtils,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { CoordinatorRevertErrors, transactionHashUtils } from '@0x/order-utils';
|
import { LibBytesRevertErrors } from '@0x/contracts-utils';
|
||||||
import { SignatureType, SignedOrder } from '@0x/types';
|
import { SignatureType, SignedOrder } from '@0x/types';
|
||||||
import { BigNumber, LibBytesRevertErrors } from '@0x/utils';
|
import { BigNumber, CoordinatorRevertErrors, hexUtils } from '@0x/utils';
|
||||||
|
|
||||||
import { ApprovalFactory, artifacts, CoordinatorContract } from '../src';
|
import { ApprovalFactory } from '../src/approval_factory';
|
||||||
|
|
||||||
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
|
import { CoordinatorContract } from './wrappers';
|
||||||
|
|
||||||
blockchainTests.resets('Mixins tests', env => {
|
blockchainTests.resets('Mixins tests', env => {
|
||||||
let chainId: number;
|
let chainId: number;
|
||||||
@@ -70,25 +74,25 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
const data = constants.NULL_BYTES;
|
const data = constants.NULL_BYTES;
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EthSign);
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EthSign);
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature);
|
const signerAddress = await mixins.getSignerAddress(transactionHash, transaction.signature).callAsync();
|
||||||
expect(transaction.signerAddress).to.eq(signerAddress);
|
expect(transaction.signerAddress).to.eq(signerAddress);
|
||||||
});
|
});
|
||||||
it('should return the correct address using the EIP712 signature type', async () => {
|
it('should return the correct address using the EIP712 signature type', async () => {
|
||||||
const data = constants.NULL_BYTES;
|
const data = constants.NULL_BYTES;
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EIP712);
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EIP712);
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature);
|
const signerAddress = await mixins.getSignerAddress(transactionHash, transaction.signature).callAsync();
|
||||||
expect(transaction.signerAddress).to.eq(signerAddress);
|
expect(transaction.signerAddress).to.eq(signerAddress);
|
||||||
});
|
});
|
||||||
it('should revert with with the Illegal signature type', async () => {
|
it('should revert with with the Illegal signature type', async () => {
|
||||||
const data = constants.NULL_BYTES;
|
const data = constants.NULL_BYTES;
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
transaction.signature = hexConcat(
|
transaction.signature = hexUtils.concat(
|
||||||
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
|
hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1),
|
||||||
SignatureType.Illegal,
|
SignatureType.Illegal,
|
||||||
);
|
);
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith(
|
||||||
new CoordinatorRevertErrors.SignatureError(
|
new CoordinatorRevertErrors.SignatureError(
|
||||||
CoordinatorRevertErrors.SignatureErrorCodes.Illegal,
|
CoordinatorRevertErrors.SignatureErrorCodes.Illegal,
|
||||||
transactionHash,
|
transactionHash,
|
||||||
@@ -99,9 +103,9 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
it('should revert with with the Invalid signature type', async () => {
|
it('should revert with with the Invalid signature type', async () => {
|
||||||
const data = constants.NULL_BYTES;
|
const data = constants.NULL_BYTES;
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
transaction.signature = hexConcat(SignatureType.Invalid);
|
transaction.signature = hexUtils.concat(SignatureType.Invalid);
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith(
|
||||||
new CoordinatorRevertErrors.SignatureError(
|
new CoordinatorRevertErrors.SignatureError(
|
||||||
CoordinatorRevertErrors.SignatureErrorCodes.Invalid,
|
CoordinatorRevertErrors.SignatureErrorCodes.Invalid,
|
||||||
transactionHash,
|
transactionHash,
|
||||||
@@ -112,12 +116,12 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
it('should revert with with a signature type that equals `NSignatureTypes`', async () => {
|
it('should revert with with a signature type that equals `NSignatureTypes`', async () => {
|
||||||
const data = constants.NULL_BYTES;
|
const data = constants.NULL_BYTES;
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
transaction.signature = hexConcat(
|
transaction.signature = hexUtils.concat(
|
||||||
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
|
hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1),
|
||||||
SignatureType.NSignatureTypes,
|
SignatureType.NSignatureTypes,
|
||||||
);
|
);
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith(
|
||||||
new CoordinatorRevertErrors.SignatureError(
|
new CoordinatorRevertErrors.SignatureError(
|
||||||
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
|
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
|
||||||
transactionHash,
|
transactionHash,
|
||||||
@@ -128,12 +132,12 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
it("should revert with with a signature type that isn't supported", async () => {
|
it("should revert with with a signature type that isn't supported", async () => {
|
||||||
const data = constants.NULL_BYTES;
|
const data = constants.NULL_BYTES;
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
transaction.signature = hexConcat(
|
transaction.signature = hexUtils.concat(
|
||||||
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
|
hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1),
|
||||||
SignatureType.Wallet,
|
SignatureType.Wallet,
|
||||||
);
|
);
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith(
|
||||||
new CoordinatorRevertErrors.SignatureError(
|
new CoordinatorRevertErrors.SignatureError(
|
||||||
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
|
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
|
||||||
transactionHash,
|
transactionHash,
|
||||||
@@ -144,11 +148,11 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('decodeOrdersFromFillData', () => {
|
describe('decodeOrdersFromFillData', () => {
|
||||||
for (const fnName of exchangeConstants.SINGLE_FILL_FN_NAMES) {
|
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
|
||||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||||
const orders = [defaultOrder];
|
const orders = [defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
|
||||||
const decodedSignedOrders = decodedOrders.map(order => ({
|
const decodedSignedOrders = decodedOrders.map(order => ({
|
||||||
...order,
|
...order,
|
||||||
signature: constants.NULL_BYTES,
|
signature: constants.NULL_BYTES,
|
||||||
@@ -158,11 +162,11 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
expect(orders).to.deep.eq(decodedSignedOrders);
|
expect(orders).to.deep.eq(decodedSignedOrders);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (const fnName of exchangeConstants.BATCH_FILL_FN_NAMES) {
|
for (const fnName of constants.BATCH_FILL_FN_NAMES) {
|
||||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
|
||||||
const decodedSignedOrders = decodedOrders.map(order => ({
|
const decodedSignedOrders = decodedOrders.map(order => ({
|
||||||
...order,
|
...order,
|
||||||
signature: constants.NULL_BYTES,
|
signature: constants.NULL_BYTES,
|
||||||
@@ -172,11 +176,11 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
expect(orders).to.deep.eq(decodedSignedOrders);
|
expect(orders).to.deep.eq(decodedSignedOrders);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (const fnName of exchangeConstants.MARKET_FILL_FN_NAMES) {
|
for (const fnName of constants.MARKET_FILL_FN_NAMES) {
|
||||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
|
||||||
const decodedSignedOrders = decodedOrders.map(order => ({
|
const decodedSignedOrders = decodedOrders.map(order => ({
|
||||||
...order,
|
...order,
|
||||||
signature: constants.NULL_BYTES,
|
signature: constants.NULL_BYTES,
|
||||||
@@ -186,11 +190,11 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
expect(orders).to.deep.eq(decodedSignedOrders);
|
expect(orders).to.deep.eq(decodedSignedOrders);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (const fnName of exchangeConstants.MATCH_ORDER_FN_NAMES) {
|
for (const fnName of constants.MATCH_ORDER_FN_NAMES) {
|
||||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
|
||||||
const decodedSignedOrders = decodedOrders.map(order => ({
|
const decodedSignedOrders = decodedOrders.map(order => ({
|
||||||
...order,
|
...order,
|
||||||
signature: constants.NULL_BYTES,
|
signature: constants.NULL_BYTES,
|
||||||
@@ -200,18 +204,18 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
expect(orders).to.deep.eq(decodedSignedOrders);
|
expect(orders).to.deep.eq(decodedSignedOrders);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (const fnName of exchangeConstants.CANCEL_ORDER_FN_NAMES) {
|
for (const fnName of constants.CANCEL_ORDER_FN_NAMES) {
|
||||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
|
||||||
const emptyArray: any[] = [];
|
const emptyArray: any[] = [];
|
||||||
expect(emptyArray).to.deep.eq(decodedOrders);
|
expect(emptyArray).to.deep.eq(decodedOrders);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
it('should decode an empty array for invalid data', async () => {
|
it('should decode an empty array for invalid data', async () => {
|
||||||
const data = '0x0123456789';
|
const data = '0x0123456789';
|
||||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
|
||||||
const emptyArray: any[] = [];
|
const emptyArray: any[] = [];
|
||||||
expect(emptyArray).to.deep.eq(decodedOrders);
|
expect(emptyArray).to.deep.eq(decodedOrders);
|
||||||
});
|
});
|
||||||
@@ -222,24 +226,22 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
new BigNumber(3), // the length of data
|
new BigNumber(3), // the length of data
|
||||||
new BigNumber(4),
|
new BigNumber(4),
|
||||||
);
|
);
|
||||||
return expect(mixins.decodeOrdersFromFillData.callAsync(data)).to.revertWith(expectedError);
|
return expect(mixins.decodeOrdersFromFillData(data).callAsync()).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Single order approvals', () => {
|
describe('Single order approvals', () => {
|
||||||
for (const fnName of exchangeConstants.SINGLE_FILL_FN_NAMES) {
|
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
|
||||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
|
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
|
||||||
const orders = [defaultOrder];
|
const orders = [defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval.signature],
|
.callAsync({ from: transactionSignerAddress });
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1]`, async () => {
|
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1]`, async () => {
|
||||||
const order = {
|
const order = {
|
||||||
@@ -249,73 +251,59 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
const orders = [order];
|
const orders = [order];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval.signature],
|
.callAsync({ from: transactionSignerAddress });
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
|
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
|
||||||
const orders = [defaultOrder];
|
const orders = [defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
|
||||||
approvalSignerAddress1,
|
.callAsync({
|
||||||
transaction.signature,
|
|
||||||
[],
|
|
||||||
{
|
|
||||||
from: approvalSignerAddress1,
|
from: approvalSignerAddress1,
|
||||||
},
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
|
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
|
||||||
const orders = [defaultOrder];
|
const orders = [defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [
|
||||||
approvalSignerAddress1,
|
approval.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval.signature],
|
.callAsync({ from: approvalSignerAddress1 });
|
||||||
{ from: approvalSignerAddress1 },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
|
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
|
||||||
const orders = [defaultOrder];
|
const orders = [defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
|
||||||
approvalSignerAddress1,
|
.callAsync({
|
||||||
transaction.signature,
|
|
||||||
[],
|
|
||||||
{
|
|
||||||
from: approvalSignerAddress1,
|
from: approvalSignerAddress1,
|
||||||
},
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid]`, async () => {
|
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid]`, async () => {
|
||||||
const orders = [defaultOrder];
|
const orders = [defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
const signature = hexConcat(
|
const signature = hexUtils.concat(
|
||||||
hexSlice(approval.signature, 0, 2),
|
hexUtils.slice(approval.signature, 0, 2),
|
||||||
'0xFFFFFFFF',
|
'0xFFFFFFFF',
|
||||||
hexSlice(approval.signature, 6),
|
hexUtils.slice(approval.signature, 6),
|
||||||
);
|
|
||||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
|
||||||
transactionSignerAddress,
|
|
||||||
transaction.signature,
|
|
||||||
[signature],
|
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
);
|
||||||
|
const tx = mixins
|
||||||
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
|
signature,
|
||||||
|
])
|
||||||
|
.callAsync({ from: transactionSignerAddress });
|
||||||
|
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(tx).to.revertWith(
|
expect(tx).to.revertWith(
|
||||||
@@ -326,37 +314,33 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
const orders = [defaultOrder];
|
const orders = [defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
|
|
||||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval.signature],
|
.callAsync({ from: approvalSignerAddress2 });
|
||||||
{ from: approvalSignerAddress2 },
|
|
||||||
);
|
|
||||||
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
describe('Batch order approvals', () => {
|
describe('Batch order approvals', () => {
|
||||||
for (const fnName of [
|
for (const fnName of [
|
||||||
...exchangeConstants.BATCH_FILL_FN_NAMES,
|
...constants.BATCH_FILL_FN_NAMES,
|
||||||
...exchangeConstants.MARKET_FILL_FN_NAMES,
|
...constants.MARKET_FILL_FN_NAMES,
|
||||||
...exchangeConstants.MATCH_ORDER_FN_NAMES,
|
...constants.MATCH_ORDER_FN_NAMES,
|
||||||
]) {
|
]) {
|
||||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval.signature],
|
.callAsync({ from: transactionSignerAddress });
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder].map(order => ({
|
const orders = [defaultOrder, defaultOrder].map(order => ({
|
||||||
@@ -365,14 +349,12 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
}));
|
}));
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval.signature],
|
.callAsync({ from: transactionSignerAddress });
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
|
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder].map(order => ({
|
const orders = [defaultOrder, defaultOrder].map(order => ({
|
||||||
@@ -381,79 +363,62 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
}));
|
}));
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
|
||||||
transactionSignerAddress,
|
.callAsync({ from: transactionSignerAddress });
|
||||||
transaction.signature,
|
|
||||||
[],
|
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
||||||
const orders = [defaultOrder, { ...defaultOrder, senderAddress: constants.NULL_ADDRESS }];
|
const orders = [defaultOrder, { ...defaultOrder, senderAddress: constants.NULL_ADDRESS }];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval.signature],
|
.callAsync({ from: transactionSignerAddress });
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2]`, async () => {
|
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2]`, async () => {
|
||||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
|
const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval1.signature,
|
||||||
transaction.signature,
|
approval2.signature,
|
||||||
[approval1.signature, approval2.signature],
|
])
|
||||||
{ from: transactionSignerAddress },
|
.callAsync({ from: transactionSignerAddress });
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
|
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
|
||||||
approvalSignerAddress1,
|
.callAsync({ from: approvalSignerAddress1 });
|
||||||
transaction.signature,
|
|
||||||
[],
|
|
||||||
{ from: approvalSignerAddress1 },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2]`, async () => {
|
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2]`, async () => {
|
||||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
|
const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
|
|
||||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval2.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval2.signature],
|
.callAsync({ from: approvalSignerAddress1 });
|
||||||
{ from: approvalSignerAddress1 },
|
|
||||||
);
|
|
||||||
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[]`, async () => {
|
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[]`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
|
||||||
transactionSignerAddress,
|
.callAsync({ from: transactionSignerAddress });
|
||||||
transaction.signature,
|
|
||||||
[],
|
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
|
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(tx).to.revertWith(
|
expect(tx).to.revertWith(
|
||||||
@@ -464,19 +429,17 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
const signature = hexConcat(
|
const signature = hexUtils.concat(
|
||||||
hexSlice(approval.signature, 0, 2),
|
hexUtils.slice(approval.signature, 0, 2),
|
||||||
'0xFFFFFFFF',
|
'0xFFFFFFFF',
|
||||||
hexSlice(approval.signature, 6),
|
hexUtils.slice(approval.signature, 6),
|
||||||
);
|
|
||||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
|
||||||
transactionSignerAddress,
|
|
||||||
transaction.signature,
|
|
||||||
[signature],
|
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
);
|
||||||
|
const tx = mixins
|
||||||
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
|
signature,
|
||||||
|
])
|
||||||
|
.callAsync({ from: transactionSignerAddress });
|
||||||
|
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(tx).to.revertWith(
|
expect(tx).to.revertWith(
|
||||||
@@ -487,20 +450,19 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
|
const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
const approvalSignature2 = hexConcat(
|
const approvalSignature2 = hexUtils.concat(
|
||||||
hexSlice(approval2.signature, 0, 2),
|
hexUtils.slice(approval2.signature, 0, 2),
|
||||||
'0xFFFFFFFF',
|
'0xFFFFFFFF',
|
||||||
hexSlice(approval2.signature, 6),
|
hexUtils.slice(approval2.signature, 6),
|
||||||
);
|
|
||||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
|
||||||
transactionSignerAddress,
|
|
||||||
transaction.signature,
|
|
||||||
[approval1.signature, approvalSignature2],
|
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
);
|
||||||
|
const tx = mixins
|
||||||
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
|
approval1.signature,
|
||||||
|
approvalSignature2,
|
||||||
|
])
|
||||||
|
.callAsync({ from: transactionSignerAddress });
|
||||||
|
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(tx).to.revertWith(
|
expect(tx).to.revertWith(
|
||||||
@@ -511,19 +473,17 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
|
const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
const approvalSignature2 = hexConcat(
|
const approvalSignature2 = hexUtils.concat(
|
||||||
hexSlice(approval2.signature, 0, 2),
|
hexUtils.slice(approval2.signature, 0, 2),
|
||||||
'0xFFFFFFFF',
|
'0xFFFFFFFF',
|
||||||
hexSlice(approval2.signature, 6),
|
hexUtils.slice(approval2.signature, 6),
|
||||||
);
|
|
||||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
|
||||||
approvalSignerAddress1,
|
|
||||||
transaction.signature,
|
|
||||||
[approvalSignature2],
|
|
||||||
{ from: approvalSignerAddress1 },
|
|
||||||
);
|
);
|
||||||
|
const tx = mixins
|
||||||
|
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [
|
||||||
|
approvalSignature2,
|
||||||
|
])
|
||||||
|
.callAsync({ from: approvalSignerAddress1 });
|
||||||
|
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(tx).to.revertWith(
|
expect(tx).to.revertWith(
|
||||||
@@ -534,15 +494,13 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
|
||||||
|
|
||||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
|
||||||
transactionSignerAddress,
|
approval1.signature,
|
||||||
transaction.signature,
|
])
|
||||||
[approval1.signature],
|
.callAsync({ from: approvalSignerAddress2 });
|
||||||
{ from: approvalSignerAddress2 },
|
|
||||||
);
|
|
||||||
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -552,36 +510,24 @@ blockchainTests.resets('Mixins tests', env => {
|
|||||||
const orders = [defaultOrder];
|
const orders = [defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
|
||||||
transactionSignerAddress,
|
.callAsync({ from: transactionSignerAddress });
|
||||||
transaction.signature,
|
|
||||||
[],
|
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it('should allow the tx signer to call `batchCancelOrders` without approval', async () => {
|
it('should allow the tx signer to call `batchCancelOrders` without approval', async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.BatchCancelOrders, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.BatchCancelOrders, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
|
||||||
transactionSignerAddress,
|
.callAsync({ from: transactionSignerAddress });
|
||||||
transaction.signature,
|
|
||||||
[],
|
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => {
|
it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => {
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
await mixins
|
||||||
transaction,
|
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
|
||||||
transactionSignerAddress,
|
.callAsync({ from: transactionSignerAddress });
|
||||||
transaction.signature,
|
|
||||||
[],
|
|
||||||
{ from: transactionSignerAddress },
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
import { hexConcat } from '@0x/contracts-test-utils';
|
|
||||||
import { eip712Utils } from '@0x/order-utils';
|
|
||||||
import { SignedZeroExTransaction } from '@0x/types';
|
|
||||||
import { signTypedDataUtils } from '@0x/utils';
|
|
||||||
|
|
||||||
export const hashUtils = {
|
|
||||||
getApprovalHashBuffer(transaction: SignedZeroExTransaction, verifyingContract: string, txOrigin: string): Buffer {
|
|
||||||
const typedData = eip712Utils.createCoordinatorApprovalTypedData(transaction, verifyingContract, txOrigin);
|
|
||||||
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
|
|
||||||
return hashBuffer;
|
|
||||||
},
|
|
||||||
getApprovalHashHex(transaction: SignedZeroExTransaction, verifyingContract: string, txOrigin: string): string {
|
|
||||||
const hashHex = hexConcat(hashUtils.getApprovalHashBuffer(transaction, verifyingContract, txOrigin));
|
|
||||||
return hashHex;
|
|
||||||
},
|
|
||||||
};
|
|
@@ -1,3 +0,0 @@
|
|||||||
export { hashUtils } from './hash_utils';
|
|
||||||
export { ApprovalFactory } from './approval_factory';
|
|
||||||
export * from './types';
|
|
19
contracts/coordinator/test/wrappers.ts
Normal file
19
contracts/coordinator/test/wrappers.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
export * from '../test/generated-wrappers/coordinator';
|
||||||
|
export * from '../test/generated-wrappers/coordinator_registry';
|
||||||
|
export * from '../test/generated-wrappers/i_coordinator_approval_verifier';
|
||||||
|
export * from '../test/generated-wrappers/i_coordinator_core';
|
||||||
|
export * from '../test/generated-wrappers/i_coordinator_registry_core';
|
||||||
|
export * from '../test/generated-wrappers/i_coordinator_signature_validator';
|
||||||
|
export * from '../test/generated-wrappers/lib_constants';
|
||||||
|
export * from '../test/generated-wrappers/lib_coordinator_approval';
|
||||||
|
export * from '../test/generated-wrappers/lib_coordinator_rich_errors';
|
||||||
|
export * from '../test/generated-wrappers/lib_e_i_p712_coordinator_domain';
|
||||||
|
export * from '../test/generated-wrappers/mixin_coordinator_approval_verifier';
|
||||||
|
export * from '../test/generated-wrappers/mixin_coordinator_core';
|
||||||
|
export * from '../test/generated-wrappers/mixin_coordinator_registry_core';
|
||||||
|
export * from '../test/generated-wrappers/mixin_signature_validator';
|
@@ -5,18 +5,24 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"generated-artifacts/Coordinator.json",
|
"generated-artifacts/Coordinator.json",
|
||||||
"generated-artifacts/CoordinatorRegistry.json",
|
"generated-artifacts/CoordinatorRegistry.json",
|
||||||
"generated-artifacts/ICoordinatorApprovalVerifier.json",
|
|
||||||
"generated-artifacts/ICoordinatorCore.json",
|
|
||||||
"generated-artifacts/ICoordinatorRegistryCore.json",
|
|
||||||
"generated-artifacts/ICoordinatorSignatureValidator.json",
|
|
||||||
"generated-artifacts/LibConstants.json",
|
"generated-artifacts/LibConstants.json",
|
||||||
"generated-artifacts/LibCoordinatorApproval.json",
|
"generated-artifacts/LibCoordinatorApproval.json",
|
||||||
"generated-artifacts/LibCoordinatorRichErrors.json",
|
"generated-artifacts/LibCoordinatorRichErrors.json",
|
||||||
"generated-artifacts/LibEIP712CoordinatorDomain.json",
|
"generated-artifacts/LibEIP712CoordinatorDomain.json",
|
||||||
"generated-artifacts/MixinCoordinatorApprovalVerifier.json",
|
"test/generated-artifacts/Coordinator.json",
|
||||||
"generated-artifacts/MixinCoordinatorCore.json",
|
"test/generated-artifacts/CoordinatorRegistry.json",
|
||||||
"generated-artifacts/MixinCoordinatorRegistryCore.json",
|
"test/generated-artifacts/ICoordinatorApprovalVerifier.json",
|
||||||
"generated-artifacts/MixinSignatureValidator.json"
|
"test/generated-artifacts/ICoordinatorCore.json",
|
||||||
|
"test/generated-artifacts/ICoordinatorRegistryCore.json",
|
||||||
|
"test/generated-artifacts/ICoordinatorSignatureValidator.json",
|
||||||
|
"test/generated-artifacts/LibConstants.json",
|
||||||
|
"test/generated-artifacts/LibCoordinatorApproval.json",
|
||||||
|
"test/generated-artifacts/LibCoordinatorRichErrors.json",
|
||||||
|
"test/generated-artifacts/LibEIP712CoordinatorDomain.json",
|
||||||
|
"test/generated-artifacts/MixinCoordinatorApprovalVerifier.json",
|
||||||
|
"test/generated-artifacts/MixinCoordinatorCore.json",
|
||||||
|
"test/generated-artifacts/MixinCoordinatorRegistryCore.json",
|
||||||
|
"test/generated-artifacts/MixinSignatureValidator.json"
|
||||||
],
|
],
|
||||||
"exclude": ["./deploy/solc/solc_bin"]
|
"exclude": ["./deploy/solc/solc_bin"]
|
||||||
}
|
}
|
||||||
|
@@ -3,5 +3,5 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "lib"
|
"outDir": "lib"
|
||||||
},
|
},
|
||||||
"include": ["./src/**/*"]
|
"include": ["./src/**/*", "./test/**/*"]
|
||||||
}
|
}
|
10
contracts/dev-utils/.npmignore
Normal file
10
contracts/dev-utils/.npmignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Blacklist all files
|
||||||
|
.*
|
||||||
|
*
|
||||||
|
# Whitelist lib
|
||||||
|
!lib/**/*
|
||||||
|
# Whitelist Solidity contracts
|
||||||
|
!contracts/src/**/*
|
||||||
|
# Blacklist tests in lib
|
||||||
|
/lib/test/*
|
||||||
|
# Package specific ignore
|
@@ -1,4 +1,91 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1575931811,
|
||||||
|
"version": "1.0.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
|
||||||
|
"pr": 2330
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add new method getOrderHash() to DevUtils contract",
|
||||||
|
"pr": 2321
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add new method getTransactionHash() to DevUtils contract",
|
||||||
|
"pr": 2321
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData",
|
||||||
|
"pr": 2034
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `revertIfInvalidAssetData` in LibAssetData",
|
||||||
|
"pr": 2034
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Use built in selectors instead of hard coded constants",
|
||||||
|
"pr": 2055
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Compile and export all contracts, artifacts, and wrappers by default",
|
||||||
|
"pr": 2055
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `marketBuy/SellOrdersNoThrow` and `marketBuy/SellOrdersFillOrKill` to `LibTransactionDecoder`.",
|
||||||
|
"pr": 2075
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "`run_mocha` package script runs with `UNLIMITED_CONTRACT_SIZE=true` environment variable.",
|
||||||
|
"pr": 2075
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575296764
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.1.0-beta.4",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575290197
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.1.0-beta.3",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1574238768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.1.0-beta.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
|
||||||
|
"pr": 2330
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add new method getOrderHash() to DevUtils contract",
|
||||||
|
"pr": 2321
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add new method getTransactionHash() to DevUtils contract",
|
||||||
|
"pr": 2321
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1574030254
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "0.1.0-beta.1",
|
"version": "0.1.0-beta.1",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@@ -5,6 +5,36 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v1.0.1 - _December 9, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.0.0 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
|
||||||
|
* Add new method getOrderHash() to DevUtils contract (#2321)
|
||||||
|
* Add new method getTransactionHash() to DevUtils contract (#2321)
|
||||||
|
* Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData (#2034)
|
||||||
|
* Add `revertIfInvalidAssetData` in LibAssetData (#2034)
|
||||||
|
* Use built in selectors instead of hard coded constants (#2055)
|
||||||
|
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
|
||||||
|
* Add `marketBuy/SellOrdersNoThrow` and `marketBuy/SellOrdersFillOrKill` to `LibTransactionDecoder`. (#2075)
|
||||||
|
* `run_mocha` package script runs with `UNLIMITED_CONTRACT_SIZE=true` environment variable. (#2075)
|
||||||
|
|
||||||
|
## v0.1.0-beta.4 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v0.1.0-beta.3 - _November 20, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v0.1.0-beta.2 - _November 17, 2019_
|
||||||
|
|
||||||
|
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
|
||||||
|
* Add new method getOrderHash() to DevUtils contract (#2321)
|
||||||
|
* Add new method getTransactionHash() to DevUtils contract (#2321)
|
||||||
|
|
||||||
## v0.1.0-beta.1 - _November 7, 2019_
|
## v0.1.0-beta.1 - _November 7, 2019_
|
||||||
|
|
||||||
* Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData (#2034)
|
* Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData (#2034)
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"artifactsDir": "./generated-artifacts",
|
"artifactsDir": "./test/generated-artifacts",
|
||||||
"contractsDir": "./contracts",
|
"contractsDir": "./contracts",
|
||||||
"useDockerisedSolc": false,
|
"useDockerisedSolc": false,
|
||||||
"isOfflineMode": false,
|
"isOfflineMode": false,
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
"evmVersion": "constantinople",
|
"evmVersion": "constantinople",
|
||||||
"optimizer": {
|
"optimizer": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"runs": 10000,
|
"runs": 1666,
|
||||||
"details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
|
"details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
|
||||||
},
|
},
|
||||||
"outputSelection": {
|
"outputSelection": {
|
||||||
|
@@ -19,6 +19,11 @@
|
|||||||
pragma solidity ^0.5.5;
|
pragma solidity ^0.5.5;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol";
|
||||||
|
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||||
|
import "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/LibEIP712.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||||
import "./OrderValidationUtils.sol";
|
import "./OrderValidationUtils.sol";
|
||||||
import "./OrderTransferSimulationUtils.sol";
|
import "./OrderTransferSimulationUtils.sol";
|
||||||
import "./LibTransactionDecoder.sol";
|
import "./LibTransactionDecoder.sol";
|
||||||
@@ -29,6 +34,7 @@ import "./EthBalanceChecker.sol";
|
|||||||
contract DevUtils is
|
contract DevUtils is
|
||||||
OrderValidationUtils,
|
OrderValidationUtils,
|
||||||
LibTransactionDecoder,
|
LibTransactionDecoder,
|
||||||
|
LibEIP712ExchangeDomain,
|
||||||
EthBalanceChecker,
|
EthBalanceChecker,
|
||||||
OrderTransferSimulationUtils
|
OrderTransferSimulationUtils
|
||||||
{
|
{
|
||||||
@@ -36,5 +42,32 @@ contract DevUtils is
|
|||||||
public
|
public
|
||||||
OrderValidationUtils(_exchange)
|
OrderValidationUtils(_exchange)
|
||||||
OrderTransferSimulationUtils(_exchange)
|
OrderTransferSimulationUtils(_exchange)
|
||||||
|
LibEIP712ExchangeDomain(uint256(0), address(0)) // null args because because we only use constants
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
function getOrderHash(LibOrder.Order memory order, uint256 chainId, address exchange)
|
||||||
|
public
|
||||||
|
pure
|
||||||
|
returns (bytes32 orderHash)
|
||||||
|
{
|
||||||
|
return LibOrder.getTypedDataHash(
|
||||||
|
order,
|
||||||
|
LibEIP712.hashEIP712Domain(_EIP712_EXCHANGE_DOMAIN_NAME, _EIP712_EXCHANGE_DOMAIN_VERSION, chainId, exchange)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTransactionHash(
|
||||||
|
LibZeroExTransaction.ZeroExTransaction memory transaction,
|
||||||
|
uint256 chainId,
|
||||||
|
address exchange
|
||||||
|
)
|
||||||
|
public
|
||||||
|
pure
|
||||||
|
returns (bytes32 transactionHash)
|
||||||
|
{
|
||||||
|
return LibZeroExTransaction.getTypedDataHash(
|
||||||
|
transaction,
|
||||||
|
LibEIP712.hashEIP712Domain(_EIP712_EXCHANGE_DOMAIN_NAME, _EIP712_EXCHANGE_DOMAIN_VERSION, chainId, exchange)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-dev-utils",
|
"name": "@0x/contracts-dev-utils",
|
||||||
"version": "0.1.0-beta.1",
|
"version": "1.0.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -8,22 +8,27 @@
|
|||||||
"main": "lib/src/index.js",
|
"main": "lib/src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yarn pre_build && tsc -b",
|
"build": "yarn pre_build && tsc -b",
|
||||||
"test": "echo !!! Run tests in @0x/contracts-tests instead !!!",
|
"test": "yarn assert_deployable && echo !!! Tests are run via @0x/contracts-tests !!!",
|
||||||
|
"assert_deployable": "node -e \"const bytecodeLen = (require('./generated-artifacts/DevUtils.json').compilerOutput.evm.bytecode.object.length-2)/2; assert(bytecodeLen<=0x6000,'DevUtils contract is too big to deploy, per EIP-170. '+bytecodeLen+'>'+0x6000)\"",
|
||||||
"build:ci": "yarn build",
|
"build:ci": "yarn build",
|
||||||
"pre_build": "run-s compile quantify_bytecode contracts:gen generate_contract_wrappers",
|
"pre_build": "run-s compile quantify_bytecode contracts:gen generate_contract_wrappers contracts:copy",
|
||||||
"compile": "sol-compiler",
|
"compile": "sol-compiler",
|
||||||
"watch": "sol-compiler -w",
|
"watch": "sol-compiler -w",
|
||||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
|
||||||
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
|
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
|
||||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||||
"contracts:gen": "contracts-gen",
|
"contracts:gen": "contracts-gen generate",
|
||||||
|
"contracts:copy": "contracts-gen copy",
|
||||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
||||||
"quantify_bytecode": "echo EVM bytecode object lengths:;for i in ./generated-artifacts/*.json; do node -e \"console.log('$i\t' + (require('$i').compilerOutput.evm.bytecode.object.length - 2) / 2)\"; done",
|
"quantify_bytecode": "echo EVM bytecode object lengths:;for i in ./test/generated-artifacts/*.json; do node -e \"console.log('$i\t' + (require('$i').compilerOutput.evm.bytecode.object.length - 2) / 2)\"; done",
|
||||||
"compile:truffle": "truffle compile"
|
"compile:truffle": "truffle compile",
|
||||||
|
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
|
||||||
|
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "./generated-artifacts/@(DevUtils|EthBalanceChecker|LibAssetData|LibTransactionDecoder|OrderTransferSimulationUtils|OrderValidationUtils).json",
|
"publicInterfaceContracts": "DevUtils,LibAssetData,LibTransactionDecoder",
|
||||||
|
"abis": "./test/generated-artifacts/@(DevUtils|EthBalanceChecker|LibAssetData|LibTransactionDecoder|OrderTransferSimulationUtils|OrderValidationUtils).json",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -36,28 +41,25 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md",
|
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^4.4.0-beta.1",
|
"@0x/abi-gen": "^5.0.1",
|
||||||
"@0x/contracts-gen": "^1.1.0-beta.1",
|
"@0x/assert": "^3.0.1",
|
||||||
"@0x/sol-compiler": "^3.2.0-beta.1",
|
"@0x/contracts-gen": "^2.0.1",
|
||||||
"@0x/tslint-config": "^3.1.0-beta.1",
|
"@0x/sol-compiler": "^4.0.1",
|
||||||
|
"@0x/ts-doc-gen": "^0.0.22",
|
||||||
|
"@0x/tslint-config": "^4.0.0",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
|
"ethereum-types": "^3.0.0",
|
||||||
|
"ethers": "~4.0.4",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
"shx": "^0.2.2",
|
"shx": "^0.2.2",
|
||||||
"solhint": "^1.4.1",
|
"solhint": "^1.4.1",
|
||||||
"truffle": "^5.0.32",
|
"truffle": "^5.0.32",
|
||||||
"tslint": "5.11.0",
|
"tslint": "5.11.0",
|
||||||
|
"typedoc": "^0.15.0",
|
||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^2.2.0-beta.1",
|
"@0x/base-contract": "^6.0.1"
|
||||||
"@0x/base-contract": "^5.5.0-beta.1",
|
|
||||||
"@0x/contract-addresses": "^3.3.0-beta.2",
|
|
||||||
"@0x/json-schemas": "^4.1.0-beta.1",
|
|
||||||
"@0x/types": "^2.5.0-beta.1",
|
|
||||||
"@0x/utils": "^4.6.0-beta.1",
|
|
||||||
"@0x/web3-wrapper": "^6.1.0-beta.1",
|
|
||||||
"ethereum-types": "^2.2.0-beta.1",
|
|
||||||
"ethers": "~4.0.4"
|
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -6,16 +6,10 @@
|
|||||||
import { ContractArtifact } from 'ethereum-types';
|
import { ContractArtifact } from 'ethereum-types';
|
||||||
|
|
||||||
import * as DevUtils from '../generated-artifacts/DevUtils.json';
|
import * as DevUtils from '../generated-artifacts/DevUtils.json';
|
||||||
import * as EthBalanceChecker from '../generated-artifacts/EthBalanceChecker.json';
|
|
||||||
import * as LibAssetData from '../generated-artifacts/LibAssetData.json';
|
import * as LibAssetData from '../generated-artifacts/LibAssetData.json';
|
||||||
import * as LibTransactionDecoder from '../generated-artifacts/LibTransactionDecoder.json';
|
import * as LibTransactionDecoder from '../generated-artifacts/LibTransactionDecoder.json';
|
||||||
import * as OrderTransferSimulationUtils from '../generated-artifacts/OrderTransferSimulationUtils.json';
|
|
||||||
import * as OrderValidationUtils from '../generated-artifacts/OrderValidationUtils.json';
|
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
DevUtils: DevUtils as ContractArtifact,
|
DevUtils: DevUtils as ContractArtifact,
|
||||||
EthBalanceChecker: EthBalanceChecker as ContractArtifact,
|
|
||||||
LibAssetData: LibAssetData as ContractArtifact,
|
LibAssetData: LibAssetData as ContractArtifact,
|
||||||
LibTransactionDecoder: LibTransactionDecoder as ContractArtifact,
|
LibTransactionDecoder: LibTransactionDecoder as ContractArtifact,
|
||||||
OrderTransferSimulationUtils: OrderTransferSimulationUtils as ContractArtifact,
|
|
||||||
OrderValidationUtils: OrderValidationUtils as ContractArtifact,
|
|
||||||
};
|
};
|
||||||
|
@@ -1,2 +1,30 @@
|
|||||||
export * from './artifacts';
|
export { artifacts } from './artifacts';
|
||||||
export * from './wrappers';
|
export { DevUtilsContract, LibAssetDataContract, LibTransactionDecoderContract } from './wrappers';
|
||||||
|
export {
|
||||||
|
ContractArtifact,
|
||||||
|
ContractChains,
|
||||||
|
CompilerOpts,
|
||||||
|
StandardContractOutput,
|
||||||
|
CompilerSettings,
|
||||||
|
ContractChainData,
|
||||||
|
ContractAbi,
|
||||||
|
DevdocOutput,
|
||||||
|
EvmOutput,
|
||||||
|
CompilerSettingsMetadata,
|
||||||
|
OptimizerSettings,
|
||||||
|
OutputField,
|
||||||
|
ParamDescription,
|
||||||
|
EvmBytecodeOutput,
|
||||||
|
AbiDefinition,
|
||||||
|
FunctionAbi,
|
||||||
|
EventAbi,
|
||||||
|
RevertErrorAbi,
|
||||||
|
EventParameter,
|
||||||
|
DataItem,
|
||||||
|
MethodAbi,
|
||||||
|
ConstructorAbi,
|
||||||
|
FallbackAbi,
|
||||||
|
ConstructorStateMutability,
|
||||||
|
TupleDataItem,
|
||||||
|
StateMutability,
|
||||||
|
} from 'ethereum-types';
|
||||||
|
@@ -4,8 +4,5 @@
|
|||||||
* -----------------------------------------------------------------------------
|
* -----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
export * from '../generated-wrappers/dev_utils';
|
export * from '../generated-wrappers/dev_utils';
|
||||||
export * from '../generated-wrappers/eth_balance_checker';
|
|
||||||
export * from '../generated-wrappers/lib_asset_data';
|
export * from '../generated-wrappers/lib_asset_data';
|
||||||
export * from '../generated-wrappers/lib_transaction_decoder';
|
export * from '../generated-wrappers/lib_transaction_decoder';
|
||||||
export * from '../generated-wrappers/order_transfer_simulation_utils';
|
|
||||||
export * from '../generated-wrappers/order_validation_utils';
|
|
||||||
|
21
contracts/dev-utils/test/artifacts.ts
Normal file
21
contracts/dev-utils/test/artifacts.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
import { ContractArtifact } from 'ethereum-types';
|
||||||
|
|
||||||
|
import * as DevUtils from '../test/generated-artifacts/DevUtils.json';
|
||||||
|
import * as EthBalanceChecker from '../test/generated-artifacts/EthBalanceChecker.json';
|
||||||
|
import * as LibAssetData from '../test/generated-artifacts/LibAssetData.json';
|
||||||
|
import * as LibTransactionDecoder from '../test/generated-artifacts/LibTransactionDecoder.json';
|
||||||
|
import * as OrderTransferSimulationUtils from '../test/generated-artifacts/OrderTransferSimulationUtils.json';
|
||||||
|
import * as OrderValidationUtils from '../test/generated-artifacts/OrderValidationUtils.json';
|
||||||
|
export const artifacts = {
|
||||||
|
DevUtils: DevUtils as ContractArtifact,
|
||||||
|
EthBalanceChecker: EthBalanceChecker as ContractArtifact,
|
||||||
|
LibAssetData: LibAssetData as ContractArtifact,
|
||||||
|
LibTransactionDecoder: LibTransactionDecoder as ContractArtifact,
|
||||||
|
OrderTransferSimulationUtils: OrderTransferSimulationUtils as ContractArtifact,
|
||||||
|
OrderValidationUtils: OrderValidationUtils as ContractArtifact,
|
||||||
|
};
|
11
contracts/dev-utils/test/wrappers.ts
Normal file
11
contracts/dev-utils/test/wrappers.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
export * from '../test/generated-wrappers/dev_utils';
|
||||||
|
export * from '../test/generated-wrappers/eth_balance_checker';
|
||||||
|
export * from '../test/generated-wrappers/lib_asset_data';
|
||||||
|
export * from '../test/generated-wrappers/lib_transaction_decoder';
|
||||||
|
export * from '../test/generated-wrappers/order_transfer_simulation_utils';
|
||||||
|
export * from '../test/generated-wrappers/order_validation_utils';
|
@@ -4,11 +4,14 @@
|
|||||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||||
"files": [
|
"files": [
|
||||||
"generated-artifacts/DevUtils.json",
|
"generated-artifacts/DevUtils.json",
|
||||||
"generated-artifacts/EthBalanceChecker.json",
|
|
||||||
"generated-artifacts/LibAssetData.json",
|
"generated-artifacts/LibAssetData.json",
|
||||||
"generated-artifacts/LibTransactionDecoder.json",
|
"generated-artifacts/LibTransactionDecoder.json",
|
||||||
"generated-artifacts/OrderTransferSimulationUtils.json",
|
"test/generated-artifacts/DevUtils.json",
|
||||||
"generated-artifacts/OrderValidationUtils.json"
|
"test/generated-artifacts/EthBalanceChecker.json",
|
||||||
|
"test/generated-artifacts/LibAssetData.json",
|
||||||
|
"test/generated-artifacts/LibTransactionDecoder.json",
|
||||||
|
"test/generated-artifacts/OrderTransferSimulationUtils.json",
|
||||||
|
"test/generated-artifacts/OrderValidationUtils.json"
|
||||||
],
|
],
|
||||||
"exclude": ["./deploy/solc/solc_bin"]
|
"exclude": ["./deploy/solc/solc_bin"]
|
||||||
}
|
}
|
||||||
|
7
contracts/dev-utils/typedoc-tsconfig.json
Normal file
7
contracts/dev-utils/typedoc-tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../typedoc-tsconfig",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "lib"
|
||||||
|
},
|
||||||
|
"include": ["./src/**/*", "./test/**/*"]
|
||||||
|
}
|
10
contracts/erc1155/.npmignore
Normal file
10
contracts/erc1155/.npmignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Blacklist all files
|
||||||
|
.*
|
||||||
|
*
|
||||||
|
# Whitelist lib
|
||||||
|
!lib/**/*
|
||||||
|
# Whitelist Solidity contracts
|
||||||
|
!contracts/src/**/*
|
||||||
|
# Blacklist tests in lib
|
||||||
|
/lib/test/*
|
||||||
|
# Package specific ignore
|
@@ -1,4 +1,59 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1575931811,
|
||||||
|
"version": "2.0.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
|
||||||
|
"pr": 2330
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `mintKnownFungibleTokensAsync()`, `isNonFungibleItemAsync()`, `isFungibleItemAsync()`, `getOwnerOfAsync()`, `getBalanceAsync()` to `Erc1155Wrapper`.",
|
||||||
|
"pr": 1819
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Replaced `SafeMath` with `LibSafeMath`",
|
||||||
|
"pr": 2254
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575296764
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.2.0-beta.4",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575290197
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.2.0-beta.3",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1574238768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.2.0-beta.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
|
||||||
|
"pr": 2330
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1574030254
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "1.2.0-beta.1",
|
"version": "1.2.0-beta.1",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@@ -5,6 +5,28 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v2.0.1 - _December 9, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.0.0 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
|
||||||
|
* Add `mintKnownFungibleTokensAsync()`, `isNonFungibleItemAsync()`, `isFungibleItemAsync()`, `getOwnerOfAsync()`, `getBalanceAsync()` to `Erc1155Wrapper`. (#1819)
|
||||||
|
* Replaced `SafeMath` with `LibSafeMath` (#2254)
|
||||||
|
|
||||||
|
## v1.2.0-beta.4 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.2.0-beta.3 - _November 20, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.2.0-beta.2 - _November 17, 2019_
|
||||||
|
|
||||||
|
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
|
||||||
|
|
||||||
## v1.2.0-beta.1 - _November 7, 2019_
|
## v1.2.0-beta.1 - _November 7, 2019_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"artifactsDir": "./generated-artifacts",
|
"artifactsDir": "./test/generated-artifacts",
|
||||||
"contractsDir": "./contracts",
|
"contractsDir": "./contracts",
|
||||||
"useDockerisedSolc": false,
|
"useDockerisedSolc": false,
|
||||||
"isOfflineMode": false,
|
"isOfflineMode": false,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-erc1155",
|
"name": "@0x/contracts-erc1155",
|
||||||
"version": "1.2.0-beta.1",
|
"version": "2.0.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yarn pre_build && tsc -b",
|
"build": "yarn pre_build && tsc -b",
|
||||||
"build:ci": "yarn build",
|
"build:ci": "yarn build",
|
||||||
"pre_build": "run-s compile contracts:gen generate_contract_wrappers",
|
"pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
|
||||||
"test": "yarn run_mocha",
|
"test": "yarn run_mocha",
|
||||||
"rebuild_and_test": "run-s build test",
|
"rebuild_and_test": "run-s build test",
|
||||||
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
||||||
@@ -21,21 +21,25 @@
|
|||||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||||
"compile": "sol-compiler",
|
"compile": "sol-compiler",
|
||||||
"watch": "sol-compiler -w",
|
"watch": "sol-compiler -w",
|
||||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
|
||||||
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
|
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
|
||||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||||
"coverage:report:text": "istanbul report text",
|
"coverage:report:text": "istanbul report text",
|
||||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||||
"coverage:report:lcov": "istanbul report lcov",
|
"coverage:report:lcov": "istanbul report lcov",
|
||||||
"test:circleci": "yarn test",
|
"test:circleci": "yarn test",
|
||||||
"contracts:gen": "contracts-gen",
|
"contracts:gen": "contracts-gen generate",
|
||||||
|
"contracts:copy": "contracts-gen copy",
|
||||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
||||||
"compile:truffle": "truffle compile"
|
"compile:truffle": "truffle compile",
|
||||||
|
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
|
||||||
|
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "./generated-artifacts/@(DummyERC1155Receiver|ERC1155|ERC1155Mintable|IERC1155|IERC1155Mintable|IERC1155Receiver|MixinNonFungibleToken).json",
|
"publicInterfaceContracts": "ERC1155,ERC1155Mintable,IERC1155Receiver,DummyERC1155Receiver",
|
||||||
|
"abis": "./test/generated-artifacts/@(DummyERC1155Receiver|ERC1155|ERC1155Mintable|IERC1155|IERC1155Mintable|IERC1155Receiver|MixinNonFungibleToken).json",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -48,11 +52,15 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^4.4.0-beta.1",
|
"@0x/abi-gen": "^5.0.1",
|
||||||
"@0x/contracts-gen": "^1.1.0-beta.1",
|
"@0x/contracts-gen": "^2.0.1",
|
||||||
"@0x/dev-utils": "^2.4.0-beta.1",
|
"@0x/contracts-utils": "^4.0.1",
|
||||||
"@0x/sol-compiler": "^3.2.0-beta.1",
|
"@0x/dev-utils": "^3.0.1",
|
||||||
"@0x/tslint-config": "^3.1.0-beta.1",
|
"@0x/sol-compiler": "^4.0.1",
|
||||||
|
"@0x/ts-doc-gen": "^0.0.22",
|
||||||
|
"@0x/tslint-config": "^4.0.0",
|
||||||
|
"@0x/types": "^3.1.0",
|
||||||
|
"@0x/typescript-typings": "^5.0.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
@@ -60,6 +68,7 @@
|
|||||||
"chai-as-promised": "^7.1.0",
|
"chai-as-promised": "^7.1.0",
|
||||||
"chai-bignumber": "^3.0.0",
|
"chai-bignumber": "^3.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
|
"ethereum-types": "^3.0.0",
|
||||||
"make-promises-safe": "^1.1.0",
|
"make-promises-safe": "^1.1.0",
|
||||||
"mocha": "^6.2.0",
|
"mocha": "^6.2.0",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
@@ -67,17 +76,14 @@
|
|||||||
"solhint": "^1.4.1",
|
"solhint": "^1.4.1",
|
||||||
"truffle": "^5.0.32",
|
"truffle": "^5.0.32",
|
||||||
"tslint": "5.11.0",
|
"tslint": "5.11.0",
|
||||||
|
"typedoc": "^0.15.0",
|
||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^5.5.0-beta.1",
|
"@0x/base-contract": "^6.0.1",
|
||||||
"@0x/contracts-test-utils": "^3.2.0-beta.1",
|
"@0x/contracts-test-utils": "^5.0.0",
|
||||||
"@0x/contracts-utils": "^3.3.0-beta.1",
|
"@0x/utils": "^5.1.0",
|
||||||
"@0x/types": "^2.5.0-beta.1",
|
"@0x/web3-wrapper": "^7.0.1",
|
||||||
"@0x/typescript-typings": "^4.4.0-beta.1",
|
|
||||||
"@0x/utils": "^4.6.0-beta.1",
|
|
||||||
"@0x/web3-wrapper": "^6.1.0-beta.1",
|
|
||||||
"ethereum-types": "^2.2.0-beta.1",
|
|
||||||
"lodash": "^4.17.11"
|
"lodash": "^4.17.11"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -8,16 +8,10 @@ import { ContractArtifact } from 'ethereum-types';
|
|||||||
import * as DummyERC1155Receiver from '../generated-artifacts/DummyERC1155Receiver.json';
|
import * as DummyERC1155Receiver from '../generated-artifacts/DummyERC1155Receiver.json';
|
||||||
import * as ERC1155 from '../generated-artifacts/ERC1155.json';
|
import * as ERC1155 from '../generated-artifacts/ERC1155.json';
|
||||||
import * as ERC1155Mintable from '../generated-artifacts/ERC1155Mintable.json';
|
import * as ERC1155Mintable from '../generated-artifacts/ERC1155Mintable.json';
|
||||||
import * as IERC1155 from '../generated-artifacts/IERC1155.json';
|
|
||||||
import * as IERC1155Mintable from '../generated-artifacts/IERC1155Mintable.json';
|
|
||||||
import * as IERC1155Receiver from '../generated-artifacts/IERC1155Receiver.json';
|
import * as IERC1155Receiver from '../generated-artifacts/IERC1155Receiver.json';
|
||||||
import * as MixinNonFungibleToken from '../generated-artifacts/MixinNonFungibleToken.json';
|
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
ERC1155: ERC1155 as ContractArtifact,
|
ERC1155: ERC1155 as ContractArtifact,
|
||||||
ERC1155Mintable: ERC1155Mintable as ContractArtifact,
|
ERC1155Mintable: ERC1155Mintable as ContractArtifact,
|
||||||
MixinNonFungibleToken: MixinNonFungibleToken as ContractArtifact,
|
|
||||||
IERC1155: IERC1155 as ContractArtifact,
|
|
||||||
IERC1155Mintable: IERC1155Mintable as ContractArtifact,
|
|
||||||
IERC1155Receiver: IERC1155Receiver as ContractArtifact,
|
IERC1155Receiver: IERC1155Receiver as ContractArtifact,
|
||||||
DummyERC1155Receiver: DummyERC1155Receiver as ContractArtifact,
|
DummyERC1155Receiver: DummyERC1155Receiver as ContractArtifact,
|
||||||
};
|
};
|
||||||
|
@@ -1,31 +1,22 @@
|
|||||||
import { LogDecoder } from '@0x/contracts-test-utils';
|
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
|
||||||
import * as chai from 'chai';
|
|
||||||
import { LogWithDecodedArgs, Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
import { LogWithDecodedArgs, Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts, ERC1155MintableContract, ERC1155TransferSingleEventArgs } from '../../src';
|
import { ERC1155MintableContract, ERC1155TransferSingleEventArgs } from './wrappers';
|
||||||
|
|
||||||
const expect = chai.expect;
|
|
||||||
|
|
||||||
export class Erc1155Wrapper {
|
export class Erc1155Wrapper {
|
||||||
private readonly _erc1155Contract: ERC1155MintableContract;
|
private readonly _erc1155Contract: ERC1155MintableContract;
|
||||||
private readonly _web3Wrapper: Web3Wrapper;
|
|
||||||
private readonly _contractOwner: string;
|
private readonly _contractOwner: string;
|
||||||
private readonly _logDecoder: LogDecoder;
|
|
||||||
|
|
||||||
constructor(contractInstance: ERC1155MintableContract, provider: Provider, contractOwner: string) {
|
constructor(contractInstance: ERC1155MintableContract, provider: Provider, contractOwner: string) {
|
||||||
this._erc1155Contract = contractInstance;
|
this._erc1155Contract = contractInstance;
|
||||||
this._web3Wrapper = new Web3Wrapper(provider);
|
|
||||||
this._contractOwner = contractOwner;
|
this._contractOwner = contractOwner;
|
||||||
this._logDecoder = new LogDecoder(this._web3Wrapper, artifacts);
|
|
||||||
}
|
}
|
||||||
public getContract(): ERC1155MintableContract {
|
public getContract(): ERC1155MintableContract {
|
||||||
return this._erc1155Contract;
|
return this._erc1155Contract;
|
||||||
}
|
}
|
||||||
public async getBalancesAsync(owners: string[], tokens: BigNumber[]): Promise<BigNumber[]> {
|
public async getBalancesAsync(owners: string[], tokens: BigNumber[]): Promise<BigNumber[]> {
|
||||||
const balances = await this._erc1155Contract.balanceOfBatch.callAsync(owners, tokens);
|
const balances = await this._erc1155Contract.balanceOfBatch(owners, tokens).callAsync();
|
||||||
return balances;
|
return balances;
|
||||||
}
|
}
|
||||||
public async safeTransferFromAsync(
|
public async safeTransferFromAsync(
|
||||||
@@ -38,11 +29,11 @@ export class Erc1155Wrapper {
|
|||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
const spender = delegatedSpender === undefined ? from : delegatedSpender;
|
const spender = delegatedSpender === undefined ? from : delegatedSpender;
|
||||||
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
|
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
|
||||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
const tx = await this._erc1155Contract
|
||||||
await this._erc1155Contract.safeTransferFrom.sendTransactionAsync(from, to, token, value, callbackDataHex, {
|
.safeTransferFrom(from, to, token, value, callbackDataHex)
|
||||||
|
.awaitTransactionSuccessAsync({
|
||||||
from: spender,
|
from: spender,
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async safeBatchTransferFromAsync(
|
public async safeBatchTransferFromAsync(
|
||||||
@@ -55,16 +46,9 @@ export class Erc1155Wrapper {
|
|||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
const spender = delegatedSpender === undefined ? from : delegatedSpender;
|
const spender = delegatedSpender === undefined ? from : delegatedSpender;
|
||||||
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
|
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
|
||||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
const tx = await this._erc1155Contract
|
||||||
await this._erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
.safeBatchTransferFrom(from, to, tokens, values, callbackDataHex)
|
||||||
from,
|
.awaitTransactionSuccessAsync({ from: spender });
|
||||||
to,
|
|
||||||
tokens,
|
|
||||||
values,
|
|
||||||
callbackDataHex,
|
|
||||||
{ from: spender },
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async mintFungibleTokensAsync(
|
public async mintFungibleTokensAsync(
|
||||||
@@ -73,11 +57,9 @@ export class Erc1155Wrapper {
|
|||||||
): Promise<BigNumber> {
|
): Promise<BigNumber> {
|
||||||
const tokenUri = 'dummyFungibleToken';
|
const tokenUri = 'dummyFungibleToken';
|
||||||
const tokenIsNonFungible = false;
|
const tokenIsNonFungible = false;
|
||||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
const tx = await this._erc1155Contract.create(tokenUri, tokenIsNonFungible).awaitTransactionSuccessAsync({
|
||||||
await this._erc1155Contract.create.sendTransactionAsync(tokenUri, tokenIsNonFungible, {
|
from: this._contractOwner,
|
||||||
from: this._contractOwner,
|
});
|
||||||
}),
|
|
||||||
);
|
|
||||||
// tslint:disable-next-line no-unnecessary-type-assertion
|
// tslint:disable-next-line no-unnecessary-type-assertion
|
||||||
const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>;
|
const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>;
|
||||||
const tokenId = createFungibleTokenLog.args.id;
|
const tokenId = createFungibleTokenLog.args.id;
|
||||||
@@ -95,25 +77,20 @@ export class Erc1155Wrapper {
|
|||||||
tokenAmountsAsArray.push(tokenAmounts);
|
tokenAmountsAsArray.push(tokenAmounts);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await this._erc1155Contract.mintFungible.awaitTransactionSuccessAsync(
|
await this._erc1155Contract
|
||||||
tokenId,
|
.mintFungible(tokenId, beneficiaries, tokenAmountsAsArray)
|
||||||
beneficiaries,
|
.awaitTransactionSuccessAsync({ from: this._contractOwner });
|
||||||
tokenAmountsAsArray,
|
|
||||||
{ from: this._contractOwner },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
public async mintNonFungibleTokensAsync(beneficiaries: string[]): Promise<[BigNumber, BigNumber[]]> {
|
public async mintNonFungibleTokensAsync(beneficiaries: string[]): Promise<[BigNumber, BigNumber[]]> {
|
||||||
const tokenUri = 'dummyNonFungibleToken';
|
const tokenUri = 'dummyNonFungibleToken';
|
||||||
const tokenIsNonFungible = true;
|
const tokenIsNonFungible = true;
|
||||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
const tx = await this._erc1155Contract.create(tokenUri, tokenIsNonFungible).awaitTransactionSuccessAsync({
|
||||||
await this._erc1155Contract.create.sendTransactionAsync(tokenUri, tokenIsNonFungible, {
|
from: this._contractOwner,
|
||||||
from: this._contractOwner,
|
});
|
||||||
}),
|
|
||||||
);
|
|
||||||
// tslint:disable-next-line no-unnecessary-type-assertion
|
// tslint:disable-next-line no-unnecessary-type-assertion
|
||||||
const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>;
|
const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>;
|
||||||
const token = createFungibleTokenLog.args.id;
|
const token = createFungibleTokenLog.args.id;
|
||||||
await this._erc1155Contract.mintNonFungible.awaitTransactionSuccessAsync(token, beneficiaries, {
|
await this._erc1155Contract.mintNonFungible(token, beneficiaries).awaitTransactionSuccessAsync({
|
||||||
from: this._contractOwner,
|
from: this._contractOwner,
|
||||||
});
|
});
|
||||||
const encodedNftIds: BigNumber[] = [];
|
const encodedNftIds: BigNumber[] = [];
|
||||||
@@ -131,15 +108,13 @@ export class Erc1155Wrapper {
|
|||||||
beneficiary: string,
|
beneficiary: string,
|
||||||
isApproved: boolean,
|
isApproved: boolean,
|
||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
const tx = await this._erc1155Contract.setApprovalForAll(beneficiary, isApproved).awaitTransactionSuccessAsync({
|
||||||
await this._erc1155Contract.setApprovalForAll.sendTransactionAsync(beneficiary, isApproved, {
|
from: owner,
|
||||||
from: owner,
|
});
|
||||||
}),
|
|
||||||
);
|
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async isApprovedForAllAsync(owner: string, beneficiary: string): Promise<boolean> {
|
public async isApprovedForAllAsync(owner: string, beneficiary: string): Promise<boolean> {
|
||||||
const isApprovedForAll = await this._erc1155Contract.isApprovedForAll.callAsync(owner, beneficiary);
|
const isApprovedForAll = await this._erc1155Contract.isApprovedForAll(owner, beneficiary).callAsync();
|
||||||
return isApprovedForAll;
|
return isApprovedForAll;
|
||||||
}
|
}
|
||||||
public async assertBalancesAsync(
|
public async assertBalancesAsync(
|
||||||
@@ -157,22 +132,24 @@ export class Erc1155Wrapper {
|
|||||||
});
|
});
|
||||||
const balances = await this.getBalancesAsync(ownersExtended, tokensExtended);
|
const balances = await this.getBalancesAsync(ownersExtended, tokensExtended);
|
||||||
_.each(balances, (balance: BigNumber, i: number) => {
|
_.each(balances, (balance: BigNumber, i: number) => {
|
||||||
expect(balance, `${ownersExtended[i]}${tokensExtended[i]}`).to.be.bignumber.equal(expectedBalances[i]);
|
if (!balance.isEqualTo(expectedBalances[i])) {
|
||||||
|
throw new Error(`${ownersExtended[i]}${tokensExtended[i]} balance not equal ${expectedBalances[i]}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public async isNonFungibleItemAsync(tokenId: BigNumber): Promise<boolean> {
|
public async isNonFungibleItemAsync(tokenId: BigNumber): Promise<boolean> {
|
||||||
return this._erc1155Contract.isNonFungibleItem.callAsync(tokenId);
|
return this._erc1155Contract.isNonFungibleItem(tokenId).callAsync();
|
||||||
}
|
}
|
||||||
public async isFungibleItemAsync(tokenId: BigNumber): Promise<boolean> {
|
public async isFungibleItemAsync(tokenId: BigNumber): Promise<boolean> {
|
||||||
return !(await this.isNonFungibleItemAsync(tokenId));
|
return !(await this.isNonFungibleItemAsync(tokenId));
|
||||||
}
|
}
|
||||||
public async getOwnerOfAsync(tokenId: BigNumber): Promise<string> {
|
public async getOwnerOfAsync(tokenId: BigNumber): Promise<string> {
|
||||||
return this._erc1155Contract.ownerOf.callAsync(tokenId);
|
return this._erc1155Contract.ownerOf(tokenId).callAsync();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @dev Get the balance of an ERC1155 token for a given owner and token ID.
|
* @dev Get the balance of an ERC1155 token for a given owner and token ID.
|
||||||
*/
|
*/
|
||||||
public async getBalanceAsync(ownerAddress: string, tokenId: BigNumber): Promise<BigNumber> {
|
public async getBalanceAsync(ownerAddress: string, tokenId: BigNumber): Promise<BigNumber> {
|
||||||
return this._erc1155Contract.balanceOf.callAsync(ownerAddress, tokenId);
|
return this._erc1155Contract.balanceOf(ownerAddress, tokenId).callAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,3 +1,45 @@
|
|||||||
export * from './wrappers';
|
export {
|
||||||
export * from './artifacts';
|
DummyERC1155ReceiverContract,
|
||||||
export { Erc1155Wrapper } from '../test/utils/erc1155_wrapper';
|
ERC1155Contract,
|
||||||
|
ERC1155MintableContract,
|
||||||
|
IERC1155ReceiverContract,
|
||||||
|
DummyERC1155ReceiverBatchTokenReceivedEventArgs,
|
||||||
|
ERC1155TransferSingleEventArgs,
|
||||||
|
} from './wrappers';
|
||||||
|
export { artifacts } from './artifacts';
|
||||||
|
export { Erc1155Wrapper } from './erc1155_wrapper';
|
||||||
|
export {
|
||||||
|
Provider,
|
||||||
|
TransactionReceiptWithDecodedLogs,
|
||||||
|
JSONRPCRequestPayload,
|
||||||
|
JSONRPCResponsePayload,
|
||||||
|
JSONRPCResponseError,
|
||||||
|
JSONRPCErrorCallback,
|
||||||
|
TransactionReceiptStatus,
|
||||||
|
ContractArtifact,
|
||||||
|
ContractChains,
|
||||||
|
CompilerOpts,
|
||||||
|
StandardContractOutput,
|
||||||
|
CompilerSettings,
|
||||||
|
ContractChainData,
|
||||||
|
ContractAbi,
|
||||||
|
DevdocOutput,
|
||||||
|
EvmOutput,
|
||||||
|
CompilerSettingsMetadata,
|
||||||
|
OptimizerSettings,
|
||||||
|
OutputField,
|
||||||
|
ParamDescription,
|
||||||
|
EvmBytecodeOutput,
|
||||||
|
AbiDefinition,
|
||||||
|
FunctionAbi,
|
||||||
|
EventAbi,
|
||||||
|
RevertErrorAbi,
|
||||||
|
EventParameter,
|
||||||
|
DataItem,
|
||||||
|
MethodAbi,
|
||||||
|
ConstructorAbi,
|
||||||
|
FallbackAbi,
|
||||||
|
ConstructorStateMutability,
|
||||||
|
TupleDataItem,
|
||||||
|
StateMutability,
|
||||||
|
} from 'ethereum-types';
|
||||||
|
@@ -6,7 +6,4 @@
|
|||||||
export * from '../generated-wrappers/dummy_erc1155_receiver';
|
export * from '../generated-wrappers/dummy_erc1155_receiver';
|
||||||
export * from '../generated-wrappers/erc1155';
|
export * from '../generated-wrappers/erc1155';
|
||||||
export * from '../generated-wrappers/erc1155_mintable';
|
export * from '../generated-wrappers/erc1155_mintable';
|
||||||
export * from '../generated-wrappers/i_erc1155_mintable';
|
|
||||||
export * from '../generated-wrappers/i_erc1155_receiver';
|
export * from '../generated-wrappers/i_erc1155_receiver';
|
||||||
export * from '../generated-wrappers/ierc1155';
|
|
||||||
export * from '../generated-wrappers/mixin_non_fungible_token';
|
|
||||||
|
23
contracts/erc1155/test/artifacts.ts
Normal file
23
contracts/erc1155/test/artifacts.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
import { ContractArtifact } from 'ethereum-types';
|
||||||
|
|
||||||
|
import * as DummyERC1155Receiver from '../test/generated-artifacts/DummyERC1155Receiver.json';
|
||||||
|
import * as ERC1155 from '../test/generated-artifacts/ERC1155.json';
|
||||||
|
import * as ERC1155Mintable from '../test/generated-artifacts/ERC1155Mintable.json';
|
||||||
|
import * as IERC1155 from '../test/generated-artifacts/IERC1155.json';
|
||||||
|
import * as IERC1155Mintable from '../test/generated-artifacts/IERC1155Mintable.json';
|
||||||
|
import * as IERC1155Receiver from '../test/generated-artifacts/IERC1155Receiver.json';
|
||||||
|
import * as MixinNonFungibleToken from '../test/generated-artifacts/MixinNonFungibleToken.json';
|
||||||
|
export const artifacts = {
|
||||||
|
ERC1155: ERC1155 as ContractArtifact,
|
||||||
|
ERC1155Mintable: ERC1155Mintable as ContractArtifact,
|
||||||
|
MixinNonFungibleToken: MixinNonFungibleToken as ContractArtifact,
|
||||||
|
IERC1155: IERC1155 as ContractArtifact,
|
||||||
|
IERC1155Mintable: IERC1155Mintable as ContractArtifact,
|
||||||
|
IERC1155Receiver: IERC1155Receiver as ContractArtifact,
|
||||||
|
DummyERC1155Receiver: DummyERC1155Receiver as ContractArtifact,
|
||||||
|
};
|
@@ -6,21 +6,19 @@ import {
|
|||||||
txDefaults,
|
txDefaults,
|
||||||
web3Wrapper,
|
web3Wrapper,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
|
import { SafeMathRevertErrors } from '@0x/contracts-utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {
|
import { Erc1155Wrapper } from '../src/erc1155_wrapper';
|
||||||
artifacts,
|
import { ERC1155MintableContract } from '../src/wrappers';
|
||||||
DummyERC1155ReceiverBatchTokenReceivedEventArgs,
|
|
||||||
DummyERC1155ReceiverContract,
|
|
||||||
ERC1155MintableContract,
|
|
||||||
} from '../src';
|
|
||||||
|
|
||||||
import { Erc1155Wrapper } from './utils/erc1155_wrapper';
|
import { artifacts } from './artifacts';
|
||||||
|
import { DummyERC1155ReceiverBatchTokenReceivedEventArgs, DummyERC1155ReceiverContract } from './wrappers';
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||||
@@ -179,14 +177,9 @@ describe('ERC1155Token', () => {
|
|||||||
valueToTransfer,
|
valueToTransfer,
|
||||||
);
|
);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
const tx = erc1155Contract.safeTransferFrom.sendTransactionAsync(
|
const tx = erc1155Contract
|
||||||
spender,
|
.safeTransferFrom(spender, receiver, tokenToTransfer, valueToTransfer, receiverCallbackData)
|
||||||
receiver,
|
.sendTransactionAsync({ from: spender });
|
||||||
tokenToTransfer,
|
|
||||||
valueToTransfer,
|
|
||||||
receiverCallbackData,
|
|
||||||
{ from: spender },
|
|
||||||
);
|
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
it('should revert if callback reverts', async () => {
|
it('should revert if callback reverts', async () => {
|
||||||
@@ -196,19 +189,14 @@ describe('ERC1155Token', () => {
|
|||||||
// set receiver to reject balances
|
// set receiver to reject balances
|
||||||
const shouldRejectTransfer = true;
|
const shouldRejectTransfer = true;
|
||||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||||
await erc1155Receiver.setRejectTransferFlag.sendTransactionAsync(shouldRejectTransfer),
|
await erc1155Receiver.setRejectTransferFlag(shouldRejectTransfer).sendTransactionAsync(),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
erc1155Contract.safeTransferFrom.sendTransactionAsync(
|
erc1155Contract
|
||||||
spender,
|
.safeTransferFrom(spender, receiver, tokenToTransfer, valueToTransfer, receiverCallbackData)
|
||||||
receiver,
|
.sendTransactionAsync({ from: spender }),
|
||||||
tokenToTransfer,
|
|
||||||
valueToTransfer,
|
|
||||||
receiverCallbackData,
|
|
||||||
{ from: spender },
|
|
||||||
),
|
|
||||||
RevertReason.TransferRejected,
|
RevertReason.TransferRejected,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -355,14 +343,9 @@ describe('ERC1155Token', () => {
|
|||||||
valuesToTransfer[0],
|
valuesToTransfer[0],
|
||||||
);
|
);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
const tx = erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
const tx = erc1155Contract
|
||||||
spender,
|
.safeBatchTransferFrom(spender, receiver, tokensToTransfer, valuesToTransfer, receiverCallbackData)
|
||||||
receiver,
|
.sendTransactionAsync({ from: spender });
|
||||||
tokensToTransfer,
|
|
||||||
valuesToTransfer,
|
|
||||||
receiverCallbackData,
|
|
||||||
{ from: spender },
|
|
||||||
);
|
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
it('should revert if callback reverts', async () => {
|
it('should revert if callback reverts', async () => {
|
||||||
@@ -372,19 +355,14 @@ describe('ERC1155Token', () => {
|
|||||||
// set receiver to reject balances
|
// set receiver to reject balances
|
||||||
const shouldRejectTransfer = true;
|
const shouldRejectTransfer = true;
|
||||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||||
await erc1155Receiver.setRejectTransferFlag.sendTransactionAsync(shouldRejectTransfer),
|
await erc1155Receiver.setRejectTransferFlag(shouldRejectTransfer).sendTransactionAsync(),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
erc1155Contract
|
||||||
spender,
|
.safeBatchTransferFrom(spender, receiver, tokensToTransfer, valuesToTransfer, receiverCallbackData)
|
||||||
receiver,
|
.sendTransactionAsync({ from: spender }),
|
||||||
tokensToTransfer,
|
|
||||||
valuesToTransfer,
|
|
||||||
receiverCallbackData,
|
|
||||||
{ from: spender },
|
|
||||||
),
|
|
||||||
RevertReason.TransferRejected,
|
RevertReason.TransferRejected,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -432,14 +410,9 @@ describe('ERC1155Token', () => {
|
|||||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, [tokenToTransfer], expectedInitialBalances);
|
await erc1155Wrapper.assertBalancesAsync(tokenHolders, [tokenToTransfer], expectedInitialBalances);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
erc1155Contract.safeTransferFrom.sendTransactionAsync(
|
erc1155Contract
|
||||||
spender,
|
.safeTransferFrom(spender, receiver, tokenToTransfer, valueToTransfer, receiverCallbackData)
|
||||||
receiver,
|
.sendTransactionAsync({ from: delegatedSpender }),
|
||||||
tokenToTransfer,
|
|
||||||
valueToTransfer,
|
|
||||||
receiverCallbackData,
|
|
||||||
{ from: delegatedSpender },
|
|
||||||
),
|
|
||||||
RevertReason.InsufficientAllowance,
|
RevertReason.InsufficientAllowance,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -485,14 +458,9 @@ describe('ERC1155Token', () => {
|
|||||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
erc1155Contract
|
||||||
spender,
|
.safeBatchTransferFrom(spender, receiver, tokensToTransfer, valuesToTransfer, receiverCallbackData)
|
||||||
receiver,
|
.sendTransactionAsync({ from: delegatedSpender }),
|
||||||
tokensToTransfer,
|
|
||||||
valuesToTransfer,
|
|
||||||
receiverCallbackData,
|
|
||||||
{ from: delegatedSpender },
|
|
||||||
),
|
|
||||||
RevertReason.InsufficientAllowance,
|
RevertReason.InsufficientAllowance,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
12
contracts/erc1155/test/wrappers.ts
Normal file
12
contracts/erc1155/test/wrappers.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
export * from '../test/generated-wrappers/dummy_erc1155_receiver';
|
||||||
|
export * from '../test/generated-wrappers/erc1155';
|
||||||
|
export * from '../test/generated-wrappers/erc1155_mintable';
|
||||||
|
export * from '../test/generated-wrappers/i_erc1155_mintable';
|
||||||
|
export * from '../test/generated-wrappers/i_erc1155_receiver';
|
||||||
|
export * from '../test/generated-wrappers/ierc1155';
|
||||||
|
export * from '../test/generated-wrappers/mixin_non_fungible_token';
|
@@ -6,10 +6,14 @@
|
|||||||
"generated-artifacts/DummyERC1155Receiver.json",
|
"generated-artifacts/DummyERC1155Receiver.json",
|
||||||
"generated-artifacts/ERC1155.json",
|
"generated-artifacts/ERC1155.json",
|
||||||
"generated-artifacts/ERC1155Mintable.json",
|
"generated-artifacts/ERC1155Mintable.json",
|
||||||
"generated-artifacts/IERC1155.json",
|
|
||||||
"generated-artifacts/IERC1155Mintable.json",
|
|
||||||
"generated-artifacts/IERC1155Receiver.json",
|
"generated-artifacts/IERC1155Receiver.json",
|
||||||
"generated-artifacts/MixinNonFungibleToken.json"
|
"test/generated-artifacts/DummyERC1155Receiver.json",
|
||||||
|
"test/generated-artifacts/ERC1155.json",
|
||||||
|
"test/generated-artifacts/ERC1155Mintable.json",
|
||||||
|
"test/generated-artifacts/IERC1155.json",
|
||||||
|
"test/generated-artifacts/IERC1155Mintable.json",
|
||||||
|
"test/generated-artifacts/IERC1155Receiver.json",
|
||||||
|
"test/generated-artifacts/MixinNonFungibleToken.json"
|
||||||
],
|
],
|
||||||
"exclude": ["./deploy/solc/solc_bin"]
|
"exclude": ["./deploy/solc/solc_bin"]
|
||||||
}
|
}
|
||||||
|
7
contracts/erc1155/typedoc-tsconfig.json
Normal file
7
contracts/erc1155/typedoc-tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../typedoc-tsconfig",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "lib"
|
||||||
|
},
|
||||||
|
"include": ["./src/**/*", "./test/**/*"]
|
||||||
|
}
|
10
contracts/erc20-bridge-sampler/.npmignore
Normal file
10
contracts/erc20-bridge-sampler/.npmignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Blacklist all files
|
||||||
|
.*
|
||||||
|
*
|
||||||
|
# Whitelist lib
|
||||||
|
!lib/**/*
|
||||||
|
# Whitelist Solidity contracts
|
||||||
|
!contracts/src/**/*
|
||||||
|
# Blacklist tests in lib
|
||||||
|
/lib/test/*
|
||||||
|
# Package specific ignore
|
39
contracts/erc20-bridge-sampler/CHANGELOG.json
Normal file
39
contracts/erc20-bridge-sampler/CHANGELOG.json
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1575931811,
|
||||||
|
"version": "1.0.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Created package.",
|
||||||
|
"pr": 2344
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575296764
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.0.0-beta.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1575290197
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.0.0-beta.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Created package.",
|
||||||
|
"pr": 2344
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
22
contracts/erc20-bridge-sampler/CHANGELOG.md
Normal file
22
contracts/erc20-bridge-sampler/CHANGELOG.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<!--
|
||||||
|
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
|
||||||
|
Edit the package's CHANGELOG.json file only.
|
||||||
|
-->
|
||||||
|
|
||||||
|
CHANGELOG
|
||||||
|
|
||||||
|
## v1.0.1 - _December 9, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.0.0 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Created package. (#2344)
|
||||||
|
|
||||||
|
## v1.0.0-beta.2 - _December 2, 2019_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.0.0-beta.1 - _Invalid date_
|
||||||
|
|
||||||
|
* Created package. (#2344)
|
1
contracts/erc20-bridge-sampler/DEPLOYS.json
Normal file
1
contracts/erc20-bridge-sampler/DEPLOYS.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[]
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user