Compare commits

..

290 Commits

Author SHA1 Message Date
fabioberger
761d0a0f18 Publish
- @0x/contracts-asset-proxy@3.0.0
 - @0x/contracts-coordinator@3.0.0
 - @0x/contracts-dev-utils@1.0.0
 - @0x/contracts-erc1155@2.0.0
 - @0x/contracts-erc20-bridge-sampler@1.0.0
 - @0x/contracts-erc20@3.0.0
 - @0x/contracts-erc721@3.0.0
 - @0x/contracts-exchange-forwarder@4.0.0
 - @0x/contracts-exchange-libs@4.0.0
 - @0x/contracts-exchange@3.0.0
 - @0x/contracts-extensions@5.0.0
 - @0x/contracts-integrations@2.0.0
 - @0x/contracts-multisig@4.0.0
 - @0x/contracts-staking@2.0.0
 - @0x/contracts-test-utils@4.0.0
 - @0x/contracts-tests@0.0.6
 - @0x/contracts-utils@4.0.0
 - 0x.js@9.0.0
 - @0x/abi-gen@5.0.0
 - @0x/assert@3.0.0
 - @0x/asset-swapper@3.0.0
 - @0x/base-contract@6.0.0
 - @0x/connect@6.0.0
 - @0x/contract-addresses@4.0.0
 - @0x/contract-artifacts@3.0.0
 - @0x/contract-wrappers-test@12.2.1
 - @0x/contract-wrappers@13.0.0
 - @0x/contracts-gen@2.0.0
 - @0x/dev-utils@3.0.0
 - ethereum-types@3.0.0
 - @0x/instant@1.0.37
 - @0x/json-schemas@5.0.0
 - @0x/migrations@5.0.0
 - @0x/monorepo-scripts@1.0.43
 - @0x/order-utils@9.0.0
 - @0x/orderbook@1.0.0
 - @0x/sol-compiler@4.0.0
 - @0x/sol-coverage@4.0.0
 - @0x/sol-doc@3.0.0
 - @0x/sol-profiler@4.0.0
 - @0x/sol-resolver@3.0.0
 - @0x/sol-trace@3.0.0
 - @0x/sol-tracing-utils@7.0.0
 - @0x/sra-spec@3.0.0
 - @0x/subproviders@6.0.0
 - @0x/tslint-config@4.0.0
 - @0x/types@3.0.0
 - @0x/typescript-typings@5.0.0
 - @0x/utils@5.0.0
 - @0x/web3-wrapper@7.0.0
2019-12-02 15:31:06 +01:00
fabioberger
ae4b1e74f9 Updated CHANGELOGS & MD docs 2019-12-02 15:30:53 +01:00
Jacob Evans
ac44618e58 Remove DIST_TAG 2019-12-03 00:44:01 +11:00
Jacob Evans
d634cbf924 Major version CHANGELOGs 2019-12-03 00:26:25 +11:00
Jacob Evans
21db0e6275 Publish
- @0x/contracts-asset-proxy@2.3.0-beta.4
 - @0x/contracts-coordinator@2.1.0-beta.4
 - @0x/contracts-dev-utils@0.1.0-beta.4
 - @0x/contracts-erc1155@1.2.0-beta.4
 - @0x/contracts-erc20-bridge-sampler@1.0.0-beta.2
 - @0x/contracts-erc20@2.3.0-beta.4
 - @0x/contracts-erc721@2.2.0-beta.4
 - @0x/contracts-exchange-forwarder@3.1.0-beta.4
 - @0x/contracts-exchange-libs@3.1.0-beta.4
 - @0x/contracts-exchange@2.2.0-beta.4
 - @0x/contracts-extensions@4.1.0-beta.4
 - @0x/contracts-integrations@1.0.3-beta.2
 - @0x/contracts-multisig@3.2.0-beta.4
 - @0x/contracts-staking@1.1.0-beta.4
 - @0x/contracts-test-utils@3.2.0-beta.4
 - @0x/contracts-tests@0.0.5
 - @0x/contracts-utils@3.3.0-beta.4
 - 0x.js@8.0.0-beta.3
 - @0x/abi-gen@4.4.0-beta.4
 - @0x/assert@2.2.0-beta.3
 - @0x/asset-swapper@2.1.0-beta.4
 - @0x/base-contract@5.5.0-beta.4
 - @0x/connect@5.1.0-beta.3
 - @0x/contract-addresses@3.3.0-beta.5
 - @0x/contract-artifacts@2.3.0-beta.4
 - @0x/contract-wrappers-test@12.2.0
 - @0x/contract-wrappers@12.2.0-beta.4
 - @0x/contracts-gen@1.1.0-beta.4
 - @0x/dev-utils@2.4.0-beta.4
 - @0x/instant@1.0.36
 - @0x/json-schemas@4.1.0-beta.3
 - @0x/migrations@4.4.0-beta.4
 - @0x/monorepo-scripts@1.0.42
 - @0x/order-utils@8.5.0-beta.4
 - @0x/orderbook@0.1.0-beta.4
 - @0x/sol-compiler@3.2.0-beta.4
 - @0x/sol-coverage@3.1.0-beta.4
 - @0x/sol-doc@2.1.0-beta.4
 - @0x/sol-profiler@3.2.0-beta.4
 - @0x/sol-resolver@2.1.0-beta.3
 - @0x/sol-trace@2.1.0-beta.4
 - @0x/sol-tracing-utils@6.1.0-beta.4
 - @0x/sra-spec@2.1.0-beta.3
 - @0x/subproviders@5.1.0-beta.3
 - @0x/types@2.5.0-beta.3
 - @0x/utils@4.6.0-beta.3
 - @0x/web3-wrapper@6.1.0-beta.3
2019-12-02 23:38:04 +11:00
Jacob Evans
ce426fd3f4 Updated CHANGELOGS & MD docs 2019-12-02 23:37:43 +11:00
Jacob Evans
b5d4c91207 Update Changelogs to beta 2019-12-02 23:11:48 +11:00
Jacob Evans
b43263be77 Merge pull request #2382 from 0xProject/fix/contract-wrappers-remove-artifacts
Remove contract-artifacts dep from contract-wrappers
2019-12-02 22:09:01 +10:00
Jacob Evans
207cf7ca24 Fix unused export 2019-12-02 22:48:09 +11:00
Jacob Evans
00e34758c4 Remove artifacts dep from contract-wrappers 2019-12-02 18:51:47 +11:00
Amir Bandeali
dd90aabad6 Merge pull request #2375 from Arctek/fix/coordinator-client
Fix for typo in constructor and gas price to apply to meta transaction.
2019-12-01 13:06:00 -08:00
Joshua Richardson
5bded1946e Fix for typo in constructor and gas price to apply to meta transaction. 2019-12-01 16:14:31 +10:30
Amir Bandeali
3642e96154 Merge pull request #2374 from 0xProject/feat/redeploy-forwarder-3.0
Redeploy 3.0 Forwarder on all networks
2019-11-30 14:17:52 -08:00
Amir Bandeali
9da09ee3a6 Update CHANGELOGs 2019-11-30 13:31:42 -08:00
Amir Bandeali
141c140f53 Update Forwarder artifact and wrapper 2019-11-30 13:31:36 -08:00
Amir Bandeali
84b660d2ef Pass in WETH address into Forwarder constructor 2019-11-29 18:20:07 -08:00
Amir Bandeali
6beedba957 Update Forwarder addresses on all networks 2019-11-29 15:55:49 -08:00
Xianny
d73982819b Deprecate abi-gen-wrappers (#2370)
* generate wrappers in @0x/contract-wrappers and delete abi-gen-wrappers

* trim exports from contract-wrappers

* separate contract-wrappers tests to get rid of dependency cycle

* remove dummy token contracts

* temporarily skip coordinator test until we can upgrade coordinator server
2019-11-27 17:50:24 -08:00
Jacob Evans
6ac5bcc907 Merge pull request #2362 from 0xProject/fix/revert-errors-utils
Re-export the RevertErrors
2019-11-27 12:27:37 +10:00
Jacob Evans
389d4d10f1 Import from @0x/utils 2019-11-27 13:02:37 +11:00
Jacob Evans
89dcbd0229 Fix import of LibBytesRevertErrors 2019-11-27 11:57:56 +11:00
Jacob Evans
ad8caa2b51 Remove moved RevertErrors 2019-11-27 11:52:14 +11:00
Jacob Evans
9c42241269 Re-export the RevertErrors 2019-11-27 11:43:12 +11:00
mzhu25
38dd45cce2 Merge pull request #2356 from 0xProject/feature/forwarder/erc20-bridge-buy
`@0x/contracts-exchange-forwarder`: ERC20Bridge buy support in Forwarder
2019-11-26 15:20:54 -08:00
Michael Zhu
aa90253c62 update TestUniswapExchangeFactory 2019-11-26 14:39:59 -08:00
Michael Zhu
41576652dc address more comments 2019-11-26 14:19:37 -08:00
Michael Zhu
74830854ca update changelogs 2019-11-26 14:16:54 -08:00
Michael Zhu
2542b1b44d address comments and tests 2019-11-26 14:16:54 -08:00
Michael Zhu
51f5e60224 static tests 2019-11-26 14:16:54 -08:00
Michael Zhu
bb5885e2bb integration tests 2019-11-26 14:16:54 -08:00
Michael Zhu
d51bbb0008 Unit tests 2019-11-26 14:16:54 -08:00
Michael Zhu
49e898b189 add ERC20Bridge buy support 2019-11-26 14:16:54 -08:00
F. Eugene Aumson
42c4fe5705 Pre-release version bumps; test fixes for latest mesh/ganache versions (#2363)
* Use pre-release ver's for tests against deployment

* Pre-release version number bumps

* pin sra_client dev deps to prereleases

for testing against deployed package

* middlewares: incl doctest in tests of deployment

* Unpin mesh, use new snapshot, & pay protocol fees

* .gitignore gen'd wrappers for new contracts

* test build_tx() & support for empty TxParams.from_

* fix doc: fill TAKERAssetAmount, not maker...
2019-11-26 13:27:49 -05:00
Jacob Evans
4b5f2c36b9 Merge pull request #2336 from 0xProject/feature/upgrade-instant-v3
Upgrade instant v3
2019-11-26 20:43:58 +10:00
Jacob Evans
935dca67e6 ERC1155 Wrapper without chai 2019-11-26 17:56:30 +11:00
Jacob Evans
d431790e19 Re-export orderHashUtils
Rather than have hacks spread through the codebase
2019-11-26 15:14:36 +11:00
Jacob Evans
56310b7bd4 Revert to abi-gen-wrappers. Clean package.json 2019-11-26 13:58:21 +11:00
Lawrence Forman
f15e21faad Merge pull request #2344 from 0xProject/feat/erc20-bridge-aggregator
ERC20BridgeSampler
2019-11-25 20:33:19 -05:00
Jacob Evans
44aa6a2b38 Clean up package.json dependencies 2019-11-26 11:33:08 +11:00
David Sun
9f32347c01 revert svg loader 2019-11-26 11:33:07 +11:00
David Sun
3d5b229c46 prettier 2019-11-26 11:33:07 +11:00
David Sun
5863ccc0a0 replay @dekz commits 2019-11-26 11:33:07 +11:00
David Sun
d220a16b99 fixed contract-wrappers again 2019-11-26 11:33:06 +11:00
David Sun
79784fc8ee fixed wrappers usage in contract-wrappers 2019-11-26 11:33:06 +11:00
David Sun
a83bc53c6a updated protocol fee utils 2019-11-26 11:33:05 +11:00
David Sun
85de0b91b1 added todo 2019-11-26 11:33:05 +11:00
Jacob Evans
d91c6e5702 Round affiliate fee for non whole amounts 2019-11-26 11:33:05 +11:00
Jacob Evans
ab7689d188 Re-enable affiliate fee 2019-11-26 11:33:05 +11:00
Jacob Evans
c81455c760 Update SwapQuoteUpdater with gas estimator 2019-11-26 11:33:04 +11:00
David Sun
39bfc97a7a fix build issues 2019-11-26 11:33:04 +11:00
David Sun
88aac78282 removed asset-buyer from residual files 2019-11-26 11:33:04 +11:00
David Sun
863e830d24 prettier + lint 2019-11-26 11:32:34 +11:00
David Sun
6c705728a4 passing instant tests 2019-11-26 11:32:34 +11:00
David Sun
7f00279ffb fixed CI tests for swapper 2019-11-26 11:32:34 +11:00
David Sun
c198d0079e prettier + minor changes 2019-11-26 11:32:33 +11:00
David Sun
1135d5a971 updated unit tests 2019-11-26 11:32:33 +11:00
David Sun
e299fa27a0 update to swapper 2019-11-26 11:32:32 +11:00
David Sun
46e0bc940a refactored and added fees 2019-11-26 11:32:32 +11:00
David Sun
9a552012f2 fixed bugs preventing build 2019-11-26 11:32:31 +11:00
David Sun
6498d385ee reworked largely all the asset-buyer legacy code 2019-11-26 11:32:30 +11:00
David Sun
dd00f2016f removed asset-buyer 2019-11-26 11:32:30 +11:00
David Sun
64d25e6522 removed buyer and adding in asset-swapper 2019-11-26 11:32:29 +11:00
Lawrence Forman
1462ab08de @0x/contracts-erc20-bridge-sampler: Clean up linter workaround in tests. 2019-11-25 17:55:12 -05:00
Lawrence Forman
a8e93a594d @0x/contracts-erc20-bridge-sampler: Throw sampling two of the same tokens.
`@0x/contracts-erc20-bridge-sampler`: Address review comments.
2019-11-25 17:48:53 -05:00
Lawrence Forman
dea30b37ef @0x/contracts-erc20-bridge-sampler: Update README and add index.ts. 2019-11-25 17:48:53 -05:00
Lawrence Forman
39571dda0b Add erc20-bridge-sampler to prettierignore 2019-11-25 17:48:53 -05:00
Lawrence Forman
c7d801b6c2 @0x/contracts-erc20-bridge-sampler: Update DEPLOYS.json 2019-11-25 17:48:53 -05:00
Lawrence Forman
57731be689 @0x/contracts-erc20-bridge-sampler: Remove gitkeep files 2019-11-25 17:48:53 -05:00
Lawrence Forman
f00524e518 @0x/contracts-erc20-bridge-sampler: Update README 2019-11-25 17:48:53 -05:00
Lawrence Forman
5567c40bae Update changelogs 2019-11-25 17:48:53 -05:00
Lawrence Forman
5d1a7613dd Add @0x/contracts-erc20-bridge-sampler to CI 2019-11-25 17:48:53 -05:00
Lawrence Forman
fa768dc112 @0x/contracts-erc20-bridge-sampler: Finish off tests. 2019-11-25 17:48:53 -05:00
Lawrence Forman
27fb51d37f @0x/contracts-asset-proxy: Tweak IUniswapExchangeFactory. 2019-11-25 17:48:53 -05:00
Lawrence Forman
d02db3864e @0x/contracts-erc20-bridge-sampler: Fix kyber bug and add test contract. 2019-11-25 17:48:53 -05:00
Lawrence Forman
a26c3036a7 @0x/contracts-erc20-bridge-sampler: Get contracts compiling. 2019-11-25 17:48:53 -05:00
Lawrence Forman
0af346aad8 @0x/contracts-erc20-bridge-aggregator: Create package.
`@0x/contracts-erc20`: Add `decimals()` to `LibERC20Token`.

`@0x/contracts-erc20-bridge-sampler`: Created package.
2019-11-25 17:48:53 -05:00
James Towle
c3c8ee7292 Merge pull request #2367 from 0xProject/feature/staking/authorizable-tests
Added unit tests for Authorizable
2019-11-25 15:59:15 -06:00
David Sun
5fbdfa66d9 Merge pull request #2368 from 0xProject/fix/reenable-builds-for-v3
Reenable CircleCi tests for swapper + orderbook, and fix migrations bug
2019-11-25 16:35:56 -05:00
David Sun
15b75715ee enable tests 2019-11-25 15:14:02 -05:00
Alex Towle
1fd92b6cbd Added unit tests for onlyAuthorized 2019-11-25 14:02:53 -06:00
David Sun
2918b5d74e add coverage for swapper 2019-11-25 14:40:35 -05:00
David Sun
669c5be344 prettier 2019-11-25 14:28:34 -05:00
Jacob Evans
e1b40ec46e Update Mesh fixtures 2019-11-26 00:07:30 +11:00
Jacob Evans
15767538eb Deploy Forwarder after Exchange is configured 2019-11-25 18:20:26 +11:00
David Sun
de2b16c464 fixed migrations 2019-11-25 01:05:24 -05:00
Alex Towle
d5e6b38450 Added unit tests for Authorizable 2019-11-24 22:55:17 -06:00
Xianny
a636e87a4f remove matchOrders; must be executed directly through Exchange contract (#2364) 2019-11-22 14:19:18 -08:00
Xianny
50d5b4fa37 Refactor/3.0/coordinator client (#2348)
* deduplicate migrateOnceAsync() test helper

* move and rename coordinator client to @0x/contracts-coordinator
2019-11-22 12:19:00 -08:00
Jacob Evans
f6d26392fb Merge pull request #2361 from 0xProject/fix/migrations-massage
Massage the migrations to match contract-addresses
2019-11-22 11:36:35 +11:00
Jacob Evans
2705bcce15 Massage the migrations to match contract-addresses 2019-11-22 11:06:07 +11:00
Fabio B
379a31ece6 Merge pull request #2355 from 0xProject/fix/increaseKeepAliveOnGanacheDockerImage
Extend keepAliveTimeout config on Ganache-cli Docker Image
2019-11-21 23:16:18 +00:00
F. Eugene Aumson
daa593d225 Updated DevUtils contract artifact (#2358)
* Add updated DevUtils contract artifact

New contract methods were added in #2321, but this artifact was not
updated.

* fix for breaking change in eth_utils
2019-11-20 20:50:49 -05:00
Amir Bandeali
ed8340affa Merge pull request #2359 from 0xProject/fix/migrations/verify-exchange-registration
Warn if Exchange contract not registered in StakingProxy
2019-11-20 16:45:38 -08:00
Amir Bandeali
b3c1e72577 Warn if Exchange contract not registered in StakingProxy 2019-11-20 16:43:02 -08:00
fabioberger
3da09d140a Extend keepAliveTimeout on Ganache-cli server to 40sec to fix Mesh issue 2019-11-20 17:36:24 +01:00
Lawrence Forman
51f254bbb1 Merge pull request #2352 from 0xProject/feat/asset-proxy/KyberBridge
KyberBridge
2019-11-20 06:20:52 -05:00
Lawrence Forman
30ee456d4c @0x/contracts-asset-proxy: Use DeploymentConstants from @0x/contracts-utils in bridges.
`@0x/contracts-asset-proxy`: Add fallback function to `KyberBridge`.
`@0x/contracts-asset-proxy`: Minor changes to `KyberBridge` contracts based on feedback.
2019-11-20 05:50:15 -05:00
Lawrence Forman
460d5f2517 @0x/contracts-utils: Add DeploymentConstants. 2019-11-20 05:50:15 -05:00
Lawrence Forman
5da1fc8445 @0x/contracts-asset-proxy: Add KyberBridge. 2019-11-20 05:50:15 -05:00
Jacob Evans
1166b43946 Publish
- @0x/contracts-asset-proxy@2.3.0-beta.3
 - @0x/contracts-coordinator@2.1.0-beta.3
 - @0x/contracts-dev-utils@0.1.0-beta.3
 - @0x/contracts-erc1155@1.2.0-beta.3
 - @0x/contracts-erc20@2.3.0-beta.3
 - @0x/contracts-erc721@2.2.0-beta.3
 - @0x/contracts-exchange-forwarder@3.1.0-beta.3
 - @0x/contracts-exchange-libs@3.1.0-beta.3
 - @0x/contracts-exchange@2.2.0-beta.3
 - @0x/contracts-extensions@4.1.0-beta.3
 - @0x/contracts-integrations@1.0.3-beta.1
 - @0x/contracts-multisig@3.2.0-beta.3
 - @0x/contracts-staking@1.1.0-beta.3
 - @0x/contracts-test-utils@3.2.0-beta.3
 - @0x/contracts-tests@0.0.4
 - @0x/contracts-utils@3.3.0-beta.3
 - 0x.js@8.0.0-beta.2
 - @0x/abi-gen-wrappers@5.4.0-beta.3
 - @0x/abi-gen@4.4.0-beta.3
 - @0x/asset-buyer@6.2.0-beta.3
 - @0x/asset-swapper@2.1.0-beta.3
 - @0x/base-contract@5.5.0-beta.3
 - @0x/contract-addresses@3.3.0-beta.4
 - @0x/contract-wrappers@12.2.0-beta.3
 - @0x/contracts-gen@1.1.0-beta.3
 - @0x/dev-utils@2.4.0-beta.3
 - @0x/instant@1.0.35
 - @0x/migrations@4.4.0-beta.3
 - @0x/monorepo-scripts@1.0.41
 - @0x/order-utils@8.5.0-beta.3
 - @0x/orderbook@0.1.0-beta.3
 - @0x/sol-compiler@3.2.0-beta.3
 - @0x/sol-coverage@3.1.0-beta.3
 - @0x/sol-doc@2.1.0-beta.3
 - @0x/sol-profiler@3.2.0-beta.3
 - @0x/sol-trace@2.1.0-beta.3
 - @0x/sol-tracing-utils@6.1.0-beta.3
2019-11-20 19:34:17 +11:00
Jacob Evans
0a6903c4c3 Updated CHANGELOGS & MD docs 2019-11-20 19:33:49 +11:00
Jacob Evans
62fae9af93 All modified CHANGELOGS are beta 2019-11-20 19:16:55 +11:00
James Towle
509a1c2eb5 Merge pull request #2328 from 0xProject/refactor/integrations/match-orders
Match Orders Integration tests
2019-11-19 16:40:52 -08:00
David Sun
8b94bbbc5e Merge pull request #2350 from 0xProject/fix/asset-swapper/rebase-and-pay-protocol-fees
asset-swapper V3 rebase, pay protocol fees, etc.
2019-11-19 16:40:15 -05:00
Alex Towle
bb923d2b7d Addressed more review feedback and fixed a bug in Actor 2019-11-19 13:03:18 -08:00
Lawrence Forman
38adc72954 @0x/asset-swapper: Remove redundant protocol fee calculation. 2019-11-19 15:11:27 -05:00
Lawrence Forman
362c7c57fa @0x/monorepo-scripts: Add Set to EXTERNAL_TYPE_MAP. 2019-11-19 14:49:38 -05:00
Lawrence Forman
6529b7eebf @0x/asset-swapper: Fix static test errors. 2019-11-19 14:49:38 -05:00
Lawrence Forman
439c98a6e5 @0x/asset-swapper: Rebase against development and pay protocol fees. 2019-11-19 14:49:38 -05:00
Lawrence Forman
32258ef666 @0x/migrations: Deploy Forwarder AFTER hooking up staking. 2019-11-19 14:49:38 -05:00
Amir Bandeali
176e088d4e Merge pull request #2349 from 0xProject/feat/3.0/migrations-patch
Redeploy 3.0 contracts
2019-11-19 07:57:24 -08:00
Alex Towle
4fe57ba025 @0x:contracts-integrations Addressed review comments 2019-11-18 17:56:07 -08:00
Alex Towle
2818e56932 @0x:contracts-integrations Addressed some lingering review comments 2019-11-18 17:56:07 -08:00
Alex Towle
5428a19617 @0x:contracts-integrations Fixed naming collision of fee recipients 2019-11-18 17:56:07 -08:00
Alex Towle
b58cbca61a @0x:contracts-integrations Addressed review feedback 2019-11-18 17:56:07 -08:00
Alex Towle
5fc6a03784 @0x:contracts-integrations Reduced reliance on DevUtils even more 2019-11-18 17:56:07 -08:00
Alex Towle
eb4ad0ba1b @0x:contracts-integrations Reduced reliance on devUtils 2019-11-18 17:56:07 -08:00
Alex Towle
72cdd1ea50 @0x:contracts-integrations Removed dependence on number_utils from staking 2019-11-18 17:56:07 -08:00
Alex Towle
18769f0b8f @0x:contracts-integrations Fixed issues after rebase 2019-11-18 17:56:07 -08:00
Alex Towle
b7d92c3c12 @0x:contracts-integrations Added tests with protocol fees for batch order matching 2019-11-18 17:56:07 -08:00
Alex Towle
b976101dca @0x:contracts-integrations Refactored match_orders_test to handle weth fees for matchOrdersWithMaximalFill 2019-11-18 17:56:07 -08:00
Alex Towle
8943b670a4 @0x:contracts-integrations Refactored match_order_test to do some testing with Weth protocol fees 2019-11-18 17:56:07 -08:00
Alex Towle
c92ff7c622 @0x:contracts-integrations Polished up match order tester 2019-11-18 17:56:07 -08:00
Alex Towle
301b5e1721 @0x:contracts-integrations Added a sanity check for different token types 2019-11-18 17:56:07 -08:00
Alex Towle
4e50b9b479 @0x:contracts-integrations Refactored match_orders_test 2019-11-18 17:56:07 -08:00
Alex Towle
f8b7b8cc28 @0x:contracts-integrations Made an initial refactor of MatchOrderTester 2019-11-18 17:56:07 -08:00
Alex Towle
2a6ea74be7 @0x:contracts-integrations Moved matchOrders into integrations 2019-11-18 17:56:06 -08:00
Jacob Evans
6d6a0c12cd Merge pull request #2343 from 0xProject/optimize/refactor-templates
abi-gen-wrappers: Move shared logic into BaseContract
2019-11-19 11:53:30 +10:00
Amir Bandeali
784a03300a Update CHANGELOGs 2019-11-18 16:10:54 -08:00
Amir Bandeali
392f578567 Make timelock configs synchronous 2019-11-18 16:10:54 -08:00
Amir Bandeali
a91b1d2dd2 Update mainnet ZrxVault in MixinDeploymentConstants 2019-11-18 16:10:54 -08:00
Amir Bandeali
400b3d961e Fix custom timelock config 2019-11-18 16:10:54 -08:00
Amir Bandeali
4f128470bd Update addresses for all networks 2019-11-18 16:10:54 -08:00
Amir Bandeali
fe06f41136 Add UniswapBridge and Eth2DaiBridge deployments to testnet migration script 2019-11-18 16:10:54 -08:00
Amir Bandeali
f81a99565e Update staking logic contract address, add UniswapBridge and Eth2DaiBridge addresses 2019-11-18 16:10:54 -08:00
Jacob Evans
81e146650b Merge branch 'development' into optimize/refactor-templates 2019-11-19 10:07:46 +10:00
Jacob Evans
bd4e04d331 Update mesh-rpc-client to 7.0.4-beta-0xv3 2019-11-19 09:55:48 +10:00
Fabio B
7663d2c64b Merge pull request #2347 from 0xProject/refactor/supportDocsForContractPackages
docs: Generate MD docs for contracts-* packages and a few others
2019-11-18 23:54:24 +00:00
fabioberger
443c3c2802 Add missing export from stakiong 2019-11-19 00:02:43 +01:00
fabioberger
17a546af5d Add more exessive type ignores 2019-11-18 23:42:45 +01:00
fabioberger
71faf46735 Add exception for EnvVars because we use it in a lot of places 2019-11-18 23:04:15 +01:00
fabioberger
ac28744df6 Stop exporting types from integrations package 2019-11-18 23:00:16 +01:00
fabioberger
adaf304b4e Add missing staking exports 2019-11-18 22:44:48 +01:00
fabioberger
16b13f9768 Fix exports from exchange 2019-11-18 22:32:47 +01:00
fabioberger
d64bf98dc0 Update mesh dep 2019-11-18 22:21:24 +01:00
Jacob Evans
71f57d13fa Update Wrappers after rebase 2019-11-18 20:43:44 +10:00
Jacob Evans
469c10e45f Fix Rich Error test bind context 2019-11-18 20:37:27 +10:00
Jacob Evans
62def596af Reuse getABIEncodedTransactionData 2019-11-18 20:37:27 +10:00
Jacob Evans
aa10844d9e Remove Lodash as a dependency in BaseContract 2019-11-18 20:37:27 +10:00
Jacob Evans
be52079182 Re-enable estimateGas in sendTransaction 2019-11-18 20:37:27 +10:00
Jacob Evans
255aca8789 Moved shared logic into BaseContract
Shared validation and default application can be moved into BaseContract

Assignment before return can be skipped here as it saves a line and
makes a dramatic difference.

Store the functionSignature once and reuse, this saving is large for
Exchange functions with order tuples.
2019-11-18 20:35:38 +10:00
fabioberger
117f4a282d Add EnvVars type 2019-11-18 10:29:25 +00:00
fabioberger
e1ea65525f Add doc generation to several more packages and fix up their index.ts files so all public interface types are exported 2019-11-18 10:29:25 +00:00
fabioberger
d0a3495b5f Refactor docgen command to also support generating docs for contracts-* packages 2019-11-18 10:24:48 +00:00
xianny
9e9e0d6592 Publish
- @0x/contracts-asset-proxy@2.3.0-beta.2
 - @0x/contracts-coordinator@2.1.0-beta.2
 - @0x/contracts-dev-utils@0.1.0-beta.2
 - @0x/contracts-erc1155@1.2.0-beta.2
 - @0x/contracts-erc20@2.3.0-beta.2
 - @0x/contracts-erc721@2.2.0-beta.2
 - @0x/contracts-exchange-forwarder@3.1.0-beta.2
 - @0x/contracts-exchange-libs@3.1.0-beta.2
 - @0x/contracts-exchange@2.2.0-beta.2
 - @0x/contracts-extensions@4.1.0-beta.2
 - @0x/contracts-integrations@1.0.2
 - @0x/contracts-multisig@3.2.0-beta.2
 - @0x/contracts-staking@1.1.0-beta.2
 - @0x/contracts-test-utils@3.2.0-beta.2
 - @0x/contracts-tests@0.0.3
 - @0x/contracts-utils@3.3.0-beta.2
 - 0x.js@8.0.0-beta.1
 - @0x/abi-gen-wrappers@5.4.0-beta.2
 - @0x/abi-gen@4.4.0-beta.2
 - @0x/assert@2.2.0-beta.2
 - @0x/asset-buyer@6.2.0-beta.2
 - @0x/asset-swapper@2.1.0-beta.2
 - @0x/base-contract@5.5.0-beta.2
 - @0x/connect@5.1.0-beta.2
 - @0x/contract-addresses@3.3.0-beta.3
 - @0x/contract-artifacts@2.3.0-beta.3
 - @0x/contract-wrappers@12.2.0-beta.2
 - @0x/contracts-gen@1.1.0-beta.2
 - @0x/dev-utils@2.4.0-beta.2
 - ethereum-types@2.2.0-beta.2
 - @0x/instant@1.0.34
 - @0x/json-schemas@4.1.0-beta.2
 - @0x/migrations@4.4.0-beta.2
 - @0x/monorepo-scripts@1.0.40
 - @0x/order-utils@8.5.0-beta.2
 - @0x/orderbook@0.1.0-beta.2
 - @0x/sol-compiler@3.2.0-beta.2
 - @0x/sol-coverage@3.1.0-beta.2
 - @0x/sol-doc@2.1.0-beta.2
 - @0x/sol-profiler@3.2.0-beta.2
 - @0x/sol-resolver@2.1.0-beta.2
 - @0x/sol-trace@2.1.0-beta.2
 - @0x/sol-tracing-utils@6.1.0-beta.2
 - @0x/sra-spec@2.1.0-beta.2
 - @0x/subproviders@5.1.0-beta.2
 - @0x/tslint-config@3.1.0-beta.2
 - @0x/types@2.5.0-beta.2
 - @0x/typescript-typings@4.4.0-beta.2
 - @0x/utils@4.6.0-beta.2
 - @0x/web3-wrapper@6.1.0-beta.2
2019-11-17 18:03:29 -05:00
xianny
cb5f9ba97d Updated CHANGELOGS & MD docs 2019-11-17 18:03:13 -05:00
xianny
34538f2ced prettier 2019-11-17 17:14:28 -05:00
xianny
2575644920 update CHANGELOG.json for beta publish 2019-11-17 17:11:35 -05:00
Greg Hysz
b4b43a9e9e Updated Coordinator wrappers and artifacts (#2346)
* Updated Coordinator wrappers and artifacts

* Use contracts-coordinator package for Coordinator

* disable custom CoordinatorWrapper

* trim disallowed artifact fields; fix exports for docs; lint
2019-11-16 19:22:22 -05:00
F. Eugene Aumson
df97b20913 abi-gen/Py: fix incorrect method return types and other small issues (#2345)
* .gitignore gen'd Python staking contract wrappers

* abi-gen/test-cli: check Python type hints in lint

* sra_client.py: Update doc for replicating examples

* abi-gen/Py: fix call() return type incl. tx hash

Previously, generated wrappers for contract methods were including type
hints that suggested that a call() (as opposed to a send_transaction())
might return either the underlying return type or a transaction hash.
This doesn't make sense because a call() will never return a TX hash.
Now, the type hint just has the return type of the underlying method.

* abi-gen: fix test_cli:lint checking wrong code

test_cli:lint is meant to be a rudimentary test of the code generated by
abi-gen.  However, previously, this script was incorporated into `yarn
lint`, and in CircleCI `static-tests` runs independently of `build`.
Consequently, the runs of test_cli:lint were checking the OLD code,
which was previously generated and checked in to git, NOT the code
generated with the version of abi-gen represented by the git repo.  Now,
test_cli:lint happens during `yarn test` rather than `yarn lint`,
because `yarn test` IS dependent on `yarn build`.

* contract_wrappers.py: fix misplaced doc

Previously, the routines `order_to_jsdict()` and `jsdict_to_order()`
were moved from contract_wrappers.exchange.types to
contract_wrappers.order_conversions.  However, the module-level
docstring describing those routines was accidentally left behind in
exchange.types.

* abi-gen/Py: stop documenting return types for TXs

Previously the send_transaction() interface included docstring
documentation for the return types of the contract method, but that
doesn't make any sense because send_transaction() returns a transaction
hash rather than any actual return values.

* abi-gen/Py: stop gen'ing send_tx for const methods

* abi-gen/Py: add build_tx to contract methods

* abi-gen/Py: fix incorrect method return types

Fixes #2298 .

* abi-gen/Py: rm validator arg to no-input methods

* abi-gen: mv Py Handlebars helpers to own module

Move all existing Python-related Handlebars helpers to the newly created
python_handlebars_helpers module.

* abi-gen: refactor internal interface

No functionality is changed.  Sole purpose of this commit is to
facilitate an upcoming commit.

* abi-gen: refactor internal interface

No functionality is changed.  Sole purpose of this commit is to
facilitate an upcoming commit.

* abi-gen/Py: name tuples w/internalType, not hash

Use the new `internalType` field on the `DataItem`s in the contract
artifact to give generated tuple classes a better name than just hashing
their component field names.

* Fix CI errors

* abi-gen/Py/wrapper: make internal member private

* Update CHANGELOGs
2019-11-15 18:27:45 -05:00
mzhu25
9e3cc379ed Merge pull request #2335 from 0xProject/refactor/integrations/move-balance-stores
`@0x/contracts-integrations`: Restructure directories, welcome core.ts and balance stores
2019-11-15 11:10:02 -08:00
Michael Zhu
c1d78a94a2 move ValidatorWalletAction to signature_validator.ts 2019-11-15 09:53:06 -08:00
Michael Zhu
7f4cbba076 Refactor integrations directory structure; move core.ts, balance stores, and FillOrderWrapper to integrations 2019-11-15 09:49:20 -08:00
Fabio B
bdca84fe72 Merge pull request #2342 from 0xProject/update/bigNumberDep
Update BigNumber dep to ~9.0.0
2019-11-15 11:53:47 +00:00
fabioberger
cf8fd7103b Add changelog entry re: BigNumber version change in packages that export BigNumber 2019-11-15 11:11:08 +00:00
fabioberger
8e8cdbd413 Update BigNumber dep to ~9.0.0 2019-11-15 11:04:53 +00:00
Jacob Evans
30f01681d4 Merge pull request #2341 from 0xProject/fix/parity-revert-errors
RevertError: Decode Parity revert errors
2019-11-15 20:31:40 +10:00
Fabio B
ecf1ad8da1 Merge pull request #2340 from 0xProject/fix/ciPublish
Fix CI test-publish
2019-11-15 10:23:28 +00:00
Jacob Evans
42dc112a13 RevertError: Decode Parity revert errors 2019-11-15 19:39:06 +10:00
Jacob Evans
58276cefce Merge pull request #2323 from 0xProject/feat/3.0-staking-ganache
ganache: Added Staking, Forwarder, ERC20Bridge
2019-11-15 13:05:37 +10:00
Amir Bandeali
4b6501a739 Merge pull request #2338 from 0xProject/fix/contracts/exchange/marketBuyOrdersNoThrow-rounding
Round up in `marketBuyOrdersNoThrow()`
2019-11-14 18:57:29 -08:00
Jacob Evans
724085e068 Remove TestStaking
CHANGELOG updates
Rebase and clean imports
Fix lint
2019-11-15 12:34:41 +10:00
Jacob Evans
21fab3ef9f Added Staking and ERC20 Bridge to migrations 2019-11-15 11:38:43 +10:00
Amir Bandeali
db8837f4ce Redeploy DevUtils and ZeroExGovernor on testnets 2019-11-15 11:34:31 +10:00
Lawrence Forman
5781cdf6da ran prettier (again) 2019-11-14 18:36:34 -05:00
Lawrence Forman
874eb1602f @0x/contracts-exchange: Round up in marketBuyOrdersNoThrow() so marketBuyOrdersFillOrKill() doesn't throw up. 2019-11-14 17:55:11 -05:00
fabioberger
82149917b7 Update mesh-rpc-client dep to latest version 2019-11-14 22:54:39 +00:00
F. Eugene Aumson
f11d8a5bd8 @0x/order-utils refactors for v3: orderParsingUtils, signatureUtils, orderHashUtils, RevertErrors, transactionHashUtils (#2321)
* move orderParsingUtils from order-utils to connect

* Remove many functions from signatureUtils

Removed from the exported object, that is.  All of them are used in
other existing code, so they were all moved to be as local to their
usage as possible.

* remove orderHashUtils.isValidOrderHash()

* Move all *RevertErrors from order-utils...

...into their respective @0x/contracts- packages.

* Refactor @0x/order-utils' orderHashUtils away

- Move existing routines into @0x/contracts-test-utils

- Migrate non-contract-test callers to a newly-exposed getOrderHash()
method in DevUtils.

* Move all *RevertErrors from @0x/utils...

...into their respective @0x/contracts- packages.

* rm transactionHashUtils.isValidTransactionHash()

* DevUtils.sol: Fail yarn test if too big to deploy

* Refactor @0x/order-utils transactionHashUtils away

- Move existing routines into @0x/contracts-test-utils

- Migrate non-contract-test callers to a newly-exposed
getTransactionHash() method in DevUtils.

* Consolidate `Removed export...` CHANGELOG entries

* Rm EthBalanceChecker from devutils wrapper exports

* Stop importing from '.' or '.../src'

* fix builds

* fix prettier; dangling promise

* increase max bundle size
2019-11-14 17:14:24 -05:00
Xianny
f0d7d10fe7 update abi-gen with new method interfaces (#2325)
* update abi-gen with new method interfaces

* wip: get all packages to build

* wip: get all packages to build

* Fix two contract wrapper calls

* Export necessary types part of the contract wrapper public interfaces

* Revive and fix wrapper_unit_tests

* Remove duplicate type

* Fix lib_exchange_rich_error_decoder tests

* Fix remaining test failures in contracts-* packages

* Prettier fixes

* remove transactionHelper

* lint and update changelogs

* Fix prettier

* Revert changes to reference docs

* Add back changelog already published and add revert changelog entry

* Add missing CHANGELOG entries

* Add missing comma

* Update mesh-rpc-client dep

* Update Mesh RPC logic in @0x/orderbook to v6.0.1-beta

* Align package versions
2019-11-14 11:22:29 -05:00
Fabio B
9d4d9ce978 Merge pull request #2337 from 0xProject/refactor/0xjsInterfaceAndDocs
Remove IWallet/IValidator from 0x.js & update doc gen
2019-11-14 15:38:04 +00:00
fabioberger
96a38602b8 Fix package.json 2019-11-14 14:57:11 +00:00
fabioberger
90d3558d31 Add CHANGELOG entry 2019-11-14 14:56:35 +00:00
fabioberger
e491a56dd0 Remove IValidator and IWallet contracts from 0x.js interface since no beginner uses them 2019-11-14 14:53:26 +00:00
fabioberger
4d8eb61924 Stop generating and uploading docs for asset-buyer since about to get removed 2019-11-14 14:51:44 +00:00
fabioberger
17fab541c6 Stop pushing ethereum-types and web3-wrapper docs to S3 since we no longer want to render them on the website 2019-11-14 14:49:55 +00:00
Amir Bandeali
91de35e8e9 Merge pull request #2333 from 0xProject/fix/staking/operator-share
Fix 100% operator share
2019-11-13 10:17:28 -08:00
Amir Bandeali
f61964676a Add test for when operatorShare == 0 2019-11-13 09:48:04 -08:00
Amir Bandeali
41a34c19bb Add zrxVault config tests in migrations 2019-11-13 09:46:33 -08:00
Amir Bandeali
d90810d127 Add tests for setting operator share to 100% 2019-11-12 22:42:55 -08:00
Amir Bandeali
7f3d281faa Allow operator share to be set to existing share 2019-11-12 20:14:48 -08:00
Greg Hysz
812c306805 Merge pull request #2332 from 0xProject/fix/staking/paramDocsForRewardsPaidOutEvent
Updated `RewardsPaid` event docs
2019-11-12 17:47:47 -08:00
Steve Klebanoff
fc1c59f374 Merge pull request #2329 from 0xProject/feature/debug-subprovider
Add DebugSubprovider
2019-11-12 15:18:00 -08:00
Amir Bandeali
35eac1e3ff Merge pull request #2322 from 0xProject/feat/3.0-mainnet-migrations
Mainnet migrations
2019-11-12 14:50:36 -08:00
Greg Hysen
e16041d7fa Updated RewardsPaid event docs 2019-11-12 14:24:39 -08:00
Amir Bandeali
b8fc84ecc8 Remove test constants from Staking ABI 2019-11-12 13:53:58 -08:00
Amir Bandeali
572c576e15 Update DevUtils addresses on all networks 2019-11-12 13:53:58 -08:00
Amir Bandeali
9df7f80fbb Move extension deployments after contract configurations 2019-11-12 13:53:58 -08:00
Amir Bandeali
f003400135 Add check for if ERC20BridgeProxy is registered in the Exchange 2019-11-12 13:53:58 -08:00
Amir Bandeali
ca7616c1d2 Update CHANGELOGs 2019-11-12 13:53:58 -08:00
Amir Bandeali
a4a2bfdf35 Finish ZrxVault and StakingProxy configs without batch transaction 2019-11-12 13:53:58 -08:00
Amir Bandeali
eb6bbb6e78 Replace Staking artifact with TestStaking to allow params to be passed into constructor 2019-11-12 13:53:58 -08:00
Amir Bandeali
4d0172f634 Fix directory to write standard input 2019-11-12 13:53:58 -08:00
Amir Bandeali
3b61e0e126 Add v3 mainnet addresses 2019-11-12 13:53:58 -08:00
Amir Bandeali
1540a91835 Update testnet migrations to do most configuration outside of batch transsaction 2019-11-12 13:53:58 -08:00
Amir Bandeali
2bcce9eed0 Add mainnet ZrxVault address to deployment constants 2019-11-12 13:53:58 -08:00
Amir Bandeali
1e53564386 Redeploy DevUtils and ZeroExGovernor on testnets 2019-11-12 13:53:58 -08:00
Amir Bandeali
d1c72706ef Add governor and staking configs for each network 2019-11-12 13:53:58 -08:00
Amir Bandeali
bd9e531257 Add flag for saving standard input during compilation 2019-11-12 13:53:58 -08:00
mzhu25
48436424db Merge pull request #2317 from 0xProject/feature/integration-tests/hot-fuzz
`@0x/contracts-integrations`: Pool management, stake management fuzz tests
2019-11-12 13:43:19 -08:00
Michael Zhu
4f10d7f859 post-rebase woes 2019-11-12 13:10:34 -08:00
Francesco Agosti
80e5a29444 Merge pull request #2326 from 0xProject/feature/remove_network_id_from_sra
Remove chainId from @0x/connect related tooling
2019-11-12 13:08:25 -08:00
F. Eugene Aumson
0ec8a4a160 sra_client.py: remove support for chainId parameter 2019-11-12 15:28:11 -05:00
F. Eugene Aumson
810bf7af0c Merge branch 'development' into feature/remove_network_id_from_sra 2019-11-12 15:26:00 -05:00
Michael Zhu
e7825206bf asyncIterator polyfill 2019-11-12 12:06:01 -08:00
Michael Zhu
2b887c336a devutils 😕 2019-11-12 12:05:39 -08:00
Michael Zhu
48ecd32d5d address comments 2019-11-12 12:05:39 -08:00
Michael Zhu
1f5a0987cb static tests, my nemesis 2019-11-12 12:05:39 -08:00
Michael Zhu
f33a9d162a moveStake assertion; use SimulationEnvironment to track global stake and staking pools 2019-11-12 12:05:38 -08:00
Michael Zhu
c2919bcdb0 tslint needs to _chill_ 2019-11-12 12:05:38 -08:00
Michael Zhu
120d554a6b split up pool/stake management simulations, change some types 2019-11-12 12:05:38 -08:00
Michael Zhu
44f268a7ee decouple state (SimulationEnvironment) and Simulation 2019-11-12 12:05:38 -08:00
Michael Zhu
3c7a0bcd85 add createStakingPool and decreaseStakingPoolOperatorShare 2019-11-12 12:05:14 -08:00
Michael Zhu
8e2e9e9331 proof of concept with a single actor and valid stakes/unstakes 2019-11-12 12:05:14 -08:00
Michael Zhu
91c26fc046 rename Result -> FunctionResult 2019-11-12 12:02:49 -08:00
Fabio B
afcfe58add Merge pull request #2330 from 0xProject/refactor/reduceContractPkgBundle
Reduce bundle-size of contracts-* packages
2019-11-13 04:00:05 +08:00
Steve Klebanoff
8d423be223 Use strings instead of bignumbers, and add JSON.stringify call 2019-11-12 11:30:24 -08:00
fabioberger
03b7314550 Disable linter for txn returning PromiseWithTransactionHash 2019-11-12 19:24:29 +00:00
fragosti
1a7e425780 Run linters 2019-11-12 11:18:23 -08:00
fabioberger
8bc5faff3c Move DeploymentManager back into test dir since only used in integrations package 2019-11-12 16:55:36 +00:00
Fabio B
2676278a66 Merge pull request #1990 from 0xProject/removeTestnetFaucet
Remove testnet-faucet from monorepo
2019-11-12 22:23:51 +08:00
fabioberger
6376b3baf3 Update yarn.lock 2019-11-12 13:50:24 +00:00
fabioberger
e569abe740 Update yarn.lock 2019-11-12 13:50:10 +00:00
fabioberger
71be9ef92a Update yarn.lock 2019-11-12 13:50:10 +00:00
fabioberger
4990c4903d Remove testnet-faucet from monorepo 2019-11-12 13:49:38 +00:00
fabioberger
9d468e2383 Move dep back since used in types 2019-11-12 13:05:25 +00:00
fabioberger
109cac013c Add CHANGELOG entries 2019-11-12 13:04:26 +00:00
fabioberger
0d8a9921cd Fix package.json 2019-11-12 12:33:09 +00:00
fabioberger
2a5f5f7312 Move deps to devDeps not used in src dir 2019-11-12 12:27:21 +00:00
fabioberger
fe54fbefbb Improve comment in npmignores 2019-11-12 11:47:11 +00:00
fabioberger
fc824b8d06 Fix prettier issues 2019-11-12 11:35:34 +00:00
fabioberger
d91a7b6d0e Add generate-artifacts and generated-wrappers nested under test dir to prettierignore 2019-11-12 11:35:28 +00:00
fabioberger
aa4b3f93fa Add ERC20 artifacts explicitly to TransactionHelper 2019-11-12 11:27:41 +00:00
fabioberger
efe8225d18 Fix import ordering 2019-11-12 10:52:04 +00:00
fabioberger
b2c0f8c158 Fix .prettierrc to proper json 2019-11-12 10:45:20 +00:00
fabioberger
66dce8794d Add missing dep 2019-11-12 10:45:08 +00:00
fabioberger
30d54407e6 Fix remaining imports 2019-11-12 10:13:25 +00:00
fabioberger
6324a92ec5 Refactor contracts-* exports so none in test dir so npmignore works as intended 2019-11-11 21:49:29 +00:00
fabioberger
67e7b5c124 Merge branch 'development' into refactor/reduceContractPkgBundle 2019-11-11 21:00:36 +00:00
Fabio B
35099d9b2f Merge pull request #2324 from 0xProject/refactor/removeUnusedContractWrappers
Remove unused contract wrappers
2019-11-12 04:59:18 +08:00
fabioberger
e07f7b54e0 Stop using directory level exports 2019-11-11 19:50:13 +00:00
fabioberger
5c409929b4 Remove ethBalanceChecker dir 2019-11-11 19:29:47 +00:00
fabioberger
1a504fdde9 Remove last references of eth_balance_checker in python tooling 2019-11-11 19:01:04 +00:00
fabioberger
4b06fd511b Uniform dep version 2019-11-11 18:18:02 +00:00
fabioberger
def6727286 Remove EthBalanceChecker from Python lib 2019-11-11 18:17:26 +00:00
fabioberger
bedaa0db16 Fix deps 2019-11-11 17:54:57 +00:00
fabioberger
90640a4fcf Fix linter 2019-11-11 17:53:07 +00:00
fabioberger
0142d07f10 Fix linter 2019-11-11 17:53:07 +00:00
fabioberger
c9d85cfc7d Remove EthBalanceChecker as standalone contract artifact/wrapper 2019-11-11 17:53:07 +00:00
fabioberger
64304c1991 Bump dummyTransactionCount to 6 to avoide changing all contract addresses now that we don't deploy DutchAuction anymore 2019-11-11 17:53:07 +00:00
fabioberger
993adc3578 Pass down DevUtils to fillOrder combinatorial tests 2019-11-11 17:53:07 +00:00
fabioberger
8813bd26f6 Pass around DevUtilsContract so it's only instantiated once 2019-11-11 17:53:07 +00:00
fabioberger
35925de320 Update CHANGELOGs 2019-11-11 17:53:07 +00:00
fabioberger
3b426a3f07 Update migration to continue deploying the old coordinator contract 2019-11-11 17:53:07 +00:00
fabioberger
5104fd5dcf Remove unused import 2019-11-11 17:53:07 +00:00
fabioberger
a5a9ca9e46 Deploy OrderValidator _not_ OrderValidationUtils in migrations script 2019-11-11 17:53:07 +00:00
fabioberger
ba0f07e3b2 Fix prettier issues 2019-11-11 17:52:32 +00:00
fabioberger
8614475324 Move TradeSide and TransferType types to contract-exchange package 2019-11-11 17:52:32 +00:00
fabioberger
744dda144b Remove unused types from order-utils export 2019-11-11 17:52:32 +00:00
fabioberger
13d47915f4 Fix linter issues 2019-11-11 17:52:32 +00:00
fabioberger
3059b85e41 Remove ZRX exports from 0x.js too 2019-11-11 17:52:32 +00:00
fabioberger
184ea4a67f Remove ZRXToken related exports 2019-11-11 17:52:32 +00:00
fabioberger
8032f536ed Add caret to version 2019-11-11 17:52:32 +00:00
fabioberger
fba3870ef1 Move ExchangeTransferSimulator into contract-exchange tests since that's the only place it's still used and we no longer want to expose it to external developers 2019-11-11 17:50:48 +00:00
fabioberger
2915ee08ea Remove ZRXToken, AssetProxies and DutchAuction contract from abi-gen-wrappers and contract-wrappers packages 2019-11-11 17:50:01 +00:00
fabioberger
86b76a3e75 Introduce publicFacingContracts config in all package.jsons, refactor all imports from src in contracts packages 2019-11-11 15:10:15 +00:00
fabioberger
bc1dca3f6f Fix contracts-gen so make sure all dirs are created 2019-11-11 12:39:36 +00:00
fabioberger
5db1820123 Only export non-test source Solidity source-code 2019-11-11 11:46:03 +00:00
Steve Klebanoff
657c35fb86 Adds CHANGELOG 2019-11-10 22:05:32 -08:00
Steve Klebanoff
9432a84468 Upgrade @types/ethereumjs-tx and add DebugSubprovider 2019-11-10 21:58:50 -08:00
fabioberger
15a5bc02ef Fix remaining build issues 2019-11-11 00:13:44 +00:00
fabioberger
f011be9347 Update all contracts-*is package.json, tsconfig.json, compiler.json, artifacts/ts and wrappers.js 2019-11-10 23:41:56 +00:00
fabioberger
b6094fdb34 Add gitignore for new generted artifacts/wrappers dirs 2019-11-10 17:23:05 +00:00
fabioberger
9e6ab9f585 First pass contracts-* separation of test and publish artifacts/wrappers 2019-11-10 17:22:29 +00:00
F. Eugene Aumson
869d2c02fa CI/test-python: give launch-kit-backend CHAIN_ID, not NETWORK_ID (#2327)
* CI/test-python: give LK ID of chain, not network

For CircleCI job test-python, change docker config for
launch-kit-backend to set an environment variable for the chain ID,
not for the network ID.  This was failing on all branches after a recent
update to the `0xorg/launch-kit-backend:v3` tag.

* Update docker config used for local testing

* Update documentation of test environment
2019-11-09 20:25:14 -05:00
fragosti
3b1dca0e70 Add asset-buyer hack 2019-11-08 17:51:25 -08:00
fragosti
595358fa69 Remove chainId when using connect from asset-swapper 2019-11-08 17:41:26 -08:00
fragosti
8a8ec79c6c Remove chainId from the orderbook pacakge 2019-11-08 16:32:22 -08:00
fragosti
6252446bd3 Update error example in SRA 2019-11-08 16:29:28 -08:00
fragosti
403ceebff9 Remove chainId from json-schemas and connect 2019-11-08 16:09:53 -08:00
fabioberger
4767882ed3 Add .npmignore to all contracts-* packages so we only publish the Solidity source and lib dir (minus tests) 2019-11-08 18:20:47 +00:00
877 changed files with 68780 additions and 121717 deletions

View File

@@ -37,7 +37,7 @@ jobs:
- store_artifacts:
path: ~/repo/packages/abi-gen/test-cli/output
- store_artifacts:
path: ~/repo/packages/abi-gen-wrappers/generated_docs
path: ~/repo/packages/contract-wrappers/generated_docs
test-contracts-ganache:
resource_class: medium+
docker:
@@ -77,7 +77,7 @@ jobs:
- restore_cache:
keys:
- 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
# 3.0. At that time, also remove exclusion from monorepo
# package.json's test script.
@@ -93,8 +93,8 @@ jobs:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: yarn test:publish:circleci
no_output_timeout: 1800
command: yarn test:publish:circleci
no_output_timeout: 1800
test-doc-generation:
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
@@ -104,8 +104,8 @@ jobs:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: yarn test:generate_docs:circleci
no_output_timeout: 1200
command: yarn test:generate_docs:circleci
no_output_timeout: 1200
test-rest:
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
@@ -116,23 +116,16 @@ jobs:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-test-utils
- run: yarn wsrun test:circleci @0x/abi-gen
# TODO (xianny): Needs to be updated for 3.0
# - 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/asset-swapper
- run: yarn wsrun test:circleci @0x/contract-artifacts
- run: yarn wsrun test:circleci @0x/assert
- 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/contract-wrappers
- run: yarn wsrun test:circleci @0x/connect
- run: yarn wsrun test:circleci @0x/contract-wrappers-test
- run: yarn wsrun test:circleci @0x/dev-utils
- run: yarn wsrun test:circleci @0x/json-schemas
- run: yarn wsrun test:circleci @0x/order-utils
# 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/orderbook
- run: yarn wsrun test:circleci @0x/orderbook
- run: yarn wsrun test:circleci @0x/sol-compiler
- run: yarn wsrun test:circleci @0x/sol-tracing-utils
- run: yarn wsrun test:circleci @0x/sol-doc
@@ -149,9 +142,9 @@ jobs:
paths:
- ~/repo/packages/assert/coverage/lcov.info
- save_cache:
key: coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }}
key: coverage-asset-swapper-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/asset-buyer/coverage/lcov.info
- ~/repo/packages/asset-swapper/coverage/lcov.info
- save_cache:
key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -161,9 +154,9 @@ jobs:
paths:
- ~/repo/packages/connect/coverage/lcov.info
- save_cache:
key: coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/contract-wrappers/coverage/lcov.info
- ~/repo/packages/contract-wrappers-test/coverage/lcov.info
- save_cache:
key: coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -202,9 +195,9 @@ jobs:
- image: nikolaik/python-nodejs:python3.7-nodejs8
- image: 0xorg/ganache-cli:4.4.0-beta.1
environment:
VERSION: 4.4.0-beta.1
VERSION: latest
SNAPSHOT_NAME: 0x_ganache_snapshot-v3-beta
- image: 0xorg/mesh:6.0.0-beta-0xv3
- image: 0xorg/mesh:0xV3
environment:
ETHEREUM_RPC_URL: 'http://localhost:8545'
ETHEREUM_NETWORK_ID: '50'
@@ -219,7 +212,7 @@ jobs:
- image: 0xorg/launch-kit-backend:v3
environment:
RPC_URL: 'http://localhost:8545'
NETWORK_ID: 50
CHAIN_ID: 1337
WHITELIST_ALL_TOKENS: True
FEE_RECIPIENT: '0x0000000000000000000000000000000000000001'
MAKER_FEE_UNIT_AMOUNT: 0
@@ -369,7 +362,7 @@ jobs:
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }}
- coverage-asset-swapper-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
@@ -378,7 +371,7 @@ jobs:
- coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
- coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}

View File

@@ -19,18 +19,15 @@ contracts: ['contracts']
@0x/sol-tracing-utils: ['packages/sol-tracing-utils']
@0x/utils: ['packages/utils']
@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/assert: ['packages/assert']
@0x/base-contract: ['packages/base-contract']
@0x/typescript-typings: ['packages/typescript-typings']
0x.js: ['packages/0x.js']
@0x/abi-gen-wrappers: ['packages/abi-gen-wrappers']
@0x/contract-artifacts: ['packages/contract-artifacts']
@0x/dev-utils: ['packages/dev-utils']
@0x/contract-wrappers: ['packages/contract-wrappers']
@0x/json-schemas: ['packages/json-schemas']
@0x/ethereum-types: ['ethereum-types']
@0x/connect: ['packages/connect']
@0x/testnet-faucets: ['packages/testnet-faucets']
@0x/monorepo-scripts: ['packages/monorepo-scripts']

41
.gitignore vendored
View File

@@ -78,28 +78,42 @@ TODO.md
# VSCode file
.vscode
# server cli
packages/testnet-faucets/server/
# generated contract artifacts/
contracts/erc20-bridge-sampler/generated-artifacts/
contracts/erc20-bridge-sampler/test/generated-artifacts/
contracts/integrations/generated-artifacts/
contracts/integrations/test/generated-artifacts/
contracts/staking/generated-artifacts/
contracts/staking/test/generated-artifacts/
contracts/coordinator/generated-artifacts/
contracts/coordinator/test/generated-artifacts/
contracts/exchange/generated-artifacts/
contracts/exchange/test/generated-artifacts/
contracts/asset-proxy/generated-artifacts/
contracts/asset-proxy/test/generated-artifacts/
contracts/multisig/generated-artifacts/
contracts/multisig/test/generated-artifacts/
contracts/utils/generated-artifacts/
contracts/utils/test/generated-artifacts/
contracts/exchange-libs/generated-artifacts/
contracts/exchange-libs/test/generated-artifacts/
contracts/erc20/generated-artifacts/
contracts/erc20/test/generated-artifacts/
contracts/erc721/generated-artifacts/
contracts/erc721/test/generated-artifacts/
contracts/erc1155/generated-artifacts/
contracts/erc1155/test/generated-artifacts/
contracts/extensions/generated-artifacts/
contracts/extensions/test/generated-artifacts/
contracts/exchange-forwarder/generated-artifacts/
contracts/exchange-forwarder/test/generated-artifacts/
contracts/dev-utils/generated-artifacts/
contracts/dev-utils/test/generated-artifacts/
packages/sol-tracing-utils/test/fixtures/artifacts/
python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/
# generated truffle contract artifacts/
contracts/erc20-bridge-sampler/build/
contracts/staking/build/
contracts/coordinator/build/
contracts/exchange/build/
@@ -116,20 +130,36 @@ contracts/dev-utils/build/
# generated contract wrappers
packages/python-contract-wrappers/generated/
contracts/erc20-bridge-sampler/generated-wrappers/
contracts/erc20-bridge-sampler/test/generated-wrappers/
contracts/integrations/generated-wrappers/
contracts/integrations/test/generated-wrappers/
contracts/staking/generated-wrappers/
contracts/staking/test/generated-wrappers/
contracts/coordinator/generated-wrappers/
contracts/coordinator/test/generated-wrappers/
contracts/exchange/generated-wrappers/
contracts/exchange/test/generated-wrappers/
contracts/asset-proxy/generated-wrappers/
contracts/asset-proxy/test/generated-wrappers/
contracts/multisig/generated-wrappers/
contracts/multisig/test/generated-wrappers/
contracts/utils/generated-wrappers/
contracts/utils/test/generated-wrappers/
contracts/exchange-libs/generated-wrappers/
contracts/exchange-libs/test/generated-wrappers/
contracts/erc20/generated-wrappers/
contracts/erc20/test/generated-wrappers/
contracts/erc721/generated-wrappers/
contracts/erc721/test/generated-wrappers/
contracts/erc1155/generated-wrappers/
contracts/erc1155/test/generated-wrappers/
contracts/extensions/generated-wrappers/
contracts/extensions/test/generated-wrappers/
contracts/exchange-forwarder/generated-wrappers/
contracts/exchange-forwarder/test/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/erc20_token/__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/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/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/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/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/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_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/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/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_vault/__init__.py
# solc-bin in sol-compiler
packages/sol-compiler/solc_bin/

View File

@@ -1,33 +1,65 @@
lib
.nyc_output
/contracts/integrations/generated-wrappers
/contracts/integrations/test/generated-wrappers
/contracts/integrations/generated-artifacts
/contracts/integrations/test/generated-artifacts
/contracts/staking/generated-wrappers
/contracts/staking/test/generated-wrappers
/contracts/staking/generated-artifacts
/contracts/staking/test/generated-artifacts
/contracts/coordinator/generated-wrappers
/contracts/coordinator/test/generated-wrappers
/contracts/coordinator/generated-artifacts
/contracts/coordinator/test/generated-artifacts
/contracts/exchange/generated-wrappers
/contracts/exchange/test/generated-wrappers
/contracts/exchange/generated-artifacts
/contracts/exchange/test/generated-artifacts
/contracts/asset-proxy/generated-wrappers
/contracts/asset-proxy/test/generated-wrappers
/contracts/asset-proxy/generated-artifacts
/contracts/asset-proxy/test/generated-artifacts
/contracts/multisig/generated-wrappers
/contracts/multisig/test/generated-wrappers
/contracts/multisig/generated-artifacts
/contracts/multisig/test/generated-artifacts
/contracts/utils/generated-wrappers
/contracts/utils/test/generated-wrappers
/contracts/utils/generated-artifacts
/contracts/utils/test/generated-artifacts
/contracts/exchange-libs/generated-wrappers
/contracts/exchange-libs/test/generated-wrappers
/contracts/exchange-libs/generated-artifacts
/contracts/exchange-libs/test/generated-artifacts
/contracts/erc20/generated-wrappers
/contracts/erc20/test/generated-wrappers
/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/test/generated-wrappers
/contracts/erc721/generated-artifacts
/contracts/erc721/test/generated-artifacts
/contracts/erc1155/generated-wrappers
/contracts/erc1155/test/generated-wrappers
/contracts/erc1155/generated-artifacts
/contracts/erc1155/test/generated-artifacts
/contracts/extensions/generated-wrappers
/contracts/extensions/test/generated-wrappers
/contracts/extensions/generated-artifacts
/contracts/extensions/test/generated-artifacts
/contracts/exchange-forwarder/generated-wrappers
/contracts/exchange-forwarder/test/generated-wrappers
/contracts/exchange-forwarder/generated-artifacts
/contracts/exchange-forwarder/test/generated-artifacts
/contracts/dev-utils/generated-wrappers
/contracts/dev-utils/test/generated-wrappers
/contracts/dev-utils/generated-artifacts
/contracts/dev-utils/test/generated-artifacts
/contracts/staking/build/
/contracts/coordinator/build/
/contracts/exchange/build/

View File

@@ -1,6 +1,6 @@
{
"tabWidth": 4,
"printWidth": 120,
"trailingComma": all,
"singleQuote": true
"tabWidth": 4,
"singleQuote": true,
"trailingComma": "all"
}

View File

@@ -5,8 +5,8 @@
# https://git-scm.com/docs/gitignore#_pattern_format
# Website
packages/asset-buyer/ @BMillman19 @fragosti @steveklebanoff
packages/instant/ @BMillman19 @fragosti @steveklebanoff
packages/asset-swapper/ @BMillman19 @fragosti @dave4506
packages/instant/ @BMillman19 @fragosti @dave4506
# Dev tools & setup
.circleci/ @LogvinovLeon

View File

@@ -61,11 +61,9 @@ These packages are all under development. See [/contracts/README.md](/contracts/
| [`@0x/order-utils`](/packages/order-utils) | [![npm](https://img.shields.io/npm/v/@0x/order-utils.svg)](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) | [![npm](https://img.shields.io/npm/v/@0x/json-schemas.svg)](https://www.npmjs.com/package/@0x/json-schemas) | 0x-related JSON schemas | |
| [`@0x/migrations`](/packages/migrations) | [![npm](https://img.shields.io/npm/v/@0x/migrations.svg)](https://www.npmjs.com/package/@0x/migrations) | Migration tool for deploying 0x smart contracts on private testnets |
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [![npm](https://img.shields.io/npm/v/@0x/contract-artifacts.svg)](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts |
| [`@0x/abi-gen-wrappers`](/packages/abi-gen-wrappers) | [![npm](https://img.shields.io/npm/v/@0x/abi-gen-wrappers.svg)](https://www.npmjs.com/package/@0x/abi-gen-wrappers) | Low-level 0x smart contract wrappers generated using `@0x/abi-gen` |
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [![npm](https://img.shields.io/npm/v/@0x/contract-artifacts.svg)](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts | |
| [`@0x/sra-spec`](/packages/sra-spec) | [![npm](https://img.shields.io/npm/v/@0x/sra-spec.svg)](https://www.npmjs.com/package/@0x/sra-spec) | OpenAPI specification for the Standard Relayer API |
| [`@0x/connect`](/packages/connect) | [![npm](https://img.shields.io/npm/v/@0x/connect.svg)](https://www.npmjs.com/package/@0x/connect) | An HTTP/WS client for interacting with the Standard Relayer API |
| [`@0x/asset-buyer`](/packages/asset-buyer) | [![npm](https://img.shields.io/npm/v/@0x/asset-buyer.svg)](https://www.npmjs.com/package/@0x/asset-buyer) | Convenience package for discovering and buying assets with Ether |
| [`@0x/asset-swapper`](/packages/asset-swapper) | [![npm](https://img.shields.io/npm/v/@0x/asset-swapper.svg)](https://www.npmjs.com/package/@0x/asset-swapper) | Convenience package for discovering and performing swaps for any ERC20 Assets |
#### Ethereum tooling
@@ -96,10 +94,9 @@ These packages are all under development. See [/contracts/README.md](/contracts/
#### Private Packages
| Package | Description |
| -------------------------------------------------- | -------------------------------------------------------------------------------- |
| [`@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 |
| Package | Description |
| ---------------------------------- | -------------------------------------------------------------------------------- |
| [`@0x/instant`](/packages/instant) | A free and flexible way to offer simple crypto purchasing in any app or website. |
## Usage

View File

@@ -13,4 +13,4 @@
#### 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.

View 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

View File

@@ -1,4 +1,83 @@
[
{
"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",
"changes": [

View File

@@ -5,6 +5,32 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## 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_
* ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract (#2034)

View File

@@ -1,5 +1,5 @@
{
"artifactsDir": "./generated-artifacts",
"artifactsDir": "./test/generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": false,
"isOfflineMode": false,

View File

@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.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/IEth2Dai.sol";
@@ -29,11 +30,9 @@ import "../interfaces/IEth2Dai.sol";
// solhint-disable space-after-comma
contract Eth2DaiBridge is
IERC20Bridge,
IWallet
IWallet,
DeploymentConstants
{
/* Mainnet addresses */
address constant public ETH2DAI_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
/// (DAI or WETH) to the Eth2Dai contract, then transfers the bought
@@ -61,8 +60,8 @@ contract Eth2DaiBridge is
LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1));
// Try to sell all of this contract's `fromTokenAddress` token balance.
uint256 boughtAmount = _getEth2DaiContract().sellAllAmount(
address(fromTokenAddress),
uint256 boughtAmount = exchange.sellAllAmount(
fromTokenAddress,
IERC20Token(fromTokenAddress).balanceOf(address(this)),
toTokenAddress,
amount
@@ -93,6 +92,6 @@ contract Eth2DaiBridge is
view
returns (IEth2Dai exchange)
{
return IEth2Dai(ETH2DAI_ADDRESS);
return IEth2Dai(_getEth2DaiAddress());
}
}

View File

@@ -0,0 +1,166 @@
/*
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 = _getKyberContract();
state.weth = _getWETHContract();
// 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;
}
/// @dev Overridable way to get the `KyberNetworkProxy` contract.
/// @return kyber The `IKyberNetworkProxy` contract.
function _getKyberContract()
internal
view
returns (IKyberNetworkProxy kyber)
{
return IKyberNetworkProxy(_getKyberNetworkProxyAddress());
}
/// @dev Overridable way to get the WETH contract.
/// @return weth The WETH contract.
function _getWETHContract()
internal
view
returns (IEtherToken weth)
{
return IEtherToken(_getWETHAddress());
}
}

View File

@@ -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/LibERC20Token.sol";
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
import "../interfaces/IUniswapExchangeFactory.sol";
import "../interfaces/IUniswapExchange.sol";
import "../interfaces/IERC20Bridge.sol";
@@ -32,12 +33,9 @@ import "../interfaces/IERC20Bridge.sol";
// solhint-disable not-rely-on-time
contract UniswapBridge is
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
// stack overflows.
struct WithdrawToState {
@@ -170,7 +168,7 @@ contract UniswapBridge is
view
returns (IEtherToken token)
{
return IEtherToken(WETH_ADDRESS);
return IEtherToken(_getWETHAddress());
}
/// @dev Overridable way to get the uniswap exchange factory contract.
@@ -180,7 +178,7 @@ contract UniswapBridge is
view
returns (IUniswapExchangeFactory factory)
{
return IUniswapExchangeFactory(UNISWAP_EXCHANGE_FACTORY_ADDRESS);
return IUniswapExchangeFactory(_getUniswapExchangeFactoryAddress());
}
/// @dev Grants an unlimited allowance to the exchange for its token
@@ -212,7 +210,9 @@ contract UniswapBridge is
if (fromTokenAddress == address(getWethContract())) {
exchangeTokenAddress = toTokenAddress;
}
exchange = getUniswapExchangeFactoryContract().getExchange(exchangeTokenAddress);
exchange = IUniswapExchange(
getUniswapExchangeFactoryContract().getExchange(exchangeTokenAddress)
);
require(address(exchange) != address(0), "NO_UNISWAP_EXCHANGE_FOR_TOKEN");
return exchange;
}

View File

@@ -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);
}

View File

@@ -67,11 +67,4 @@ interface IUniswapExchange {
)
external
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);
}

View File

@@ -28,5 +28,5 @@ interface IUniswapExchangeFactory {
function getExchange(address tokenAddress)
external
view
returns (IUniswapExchange);
returns (address);
}

View 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 _getKyberContract()
internal
view
returns (IKyberNetworkProxy kyber)
{
return IKyberNetworkProxy(address(this));
}
// @dev overridden to point to test WETH.
function _getWETHContract()
internal
view
returns (IEtherToken weth_)
{
return weth;
}
}

View File

@@ -407,9 +407,9 @@ contract TestUniswapBridge is
function getExchange(address tokenAddress)
external
view
returns (IUniswapExchange)
returns (address)
{
return IUniswapExchange(_testExchanges[tokenAddress]);
return address(_testExchanges[tokenAddress]);
}
// @dev Use `wethToken`.

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-asset-proxy",
"version": "2.3.0-beta.1",
"version": "3.0.0",
"engines": {
"node": ">=6.12"
},
@@ -12,7 +12,7 @@
"scripts": {
"build": "yarn pre_build && tsc -b",
"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",
"rebuild_and_test": "run-s build test",
"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",
"compile": "sol-compiler",
"watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"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 test/generated-wrappers --backend ethers",
"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 ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage: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",
"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",
"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": {
"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,TestStaticCallTarget",
"abis": "./test/generated-artifacts/@(ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
@@ -48,12 +52,15 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
"devDependencies": {
"@0x/abi-gen": "^4.4.0-beta.1",
"@0x/contracts-gen": "^1.1.0-beta.1",
"@0x/contracts-test-utils": "^3.2.0-beta.1",
"@0x/dev-utils": "^2.4.0-beta.1",
"@0x/sol-compiler": "^3.2.0-beta.1",
"@0x/tslint-config": "^3.1.0-beta.1",
"@0x/abi-gen": "^5.0.0",
"@0x/contracts-gen": "^2.0.0",
"@0x/contracts-test-utils": "^4.0.0",
"@0x/contracts-utils": "^4.0.0",
"@0x/dev-utils": "^3.0.0",
"@0x/sol-compiler": "^4.0.0",
"@0x/ts-doc-gen": "^0.0.22",
"@0x/tslint-config": "^4.0.0",
"@0x/types": "^3.0.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "*",
@@ -61,6 +68,7 @@
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"ethereumjs-util": "^5.1.1",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
"npm-run-all": "^4.1.2",
@@ -68,22 +76,20 @@
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typedoc": "^0.15.0",
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.5.0-beta.1",
"@0x/contracts-dev-utils": "^0.1.0-beta.1",
"@0x/contracts-erc1155": "^1.2.0-beta.1",
"@0x/contracts-erc20": "^2.3.0-beta.1",
"@0x/contracts-erc721": "^2.2.0-beta.1",
"@0x/contracts-utils": "^3.3.0-beta.1",
"@0x/order-utils": "^8.5.0-beta.1",
"@0x/types": "^2.5.0-beta.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",
"ethereumjs-util": "^5.1.1",
"@0x/base-contract": "^6.0.0",
"@0x/contracts-dev-utils": "^1.0.0",
"@0x/contracts-erc1155": "^2.0.0",
"@0x/contracts-erc20": "^3.0.0",
"@0x/contracts-erc721": "^3.0.0",
"@0x/order-utils": "^9.0.0",
"@0x/typescript-typings": "^5.0.0",
"@0x/utils": "^5.0.0",
"@0x/web3-wrapper": "^7.0.0",
"ethereum-types": "^3.0.0",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -12,44 +12,22 @@ import * as ERC721Proxy from '../generated-artifacts/ERC721Proxy.json';
import * as Eth2DaiBridge from '../generated-artifacts/Eth2DaiBridge.json';
import * as IAssetData from '../generated-artifacts/IAssetData.json';
import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json';
import * as IAssetProxyDispatcher from '../generated-artifacts/IAssetProxyDispatcher.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 KyberBridge from '../generated-artifacts/KyberBridge.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 TestERC20Bridge from '../generated-artifacts/TestERC20Bridge.json';
import * as TestEth2DaiBridge from '../generated-artifacts/TestEth2DaiBridge.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';
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,
ERC20BridgeProxy: ERC20BridgeProxy as ContractArtifact,
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
UniswapBridge: UniswapBridge as ContractArtifact,
IAssetData: IAssetData as ContractArtifact,
IAssetProxy: IAssetProxy as ContractArtifact,
IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact,
IAuthorizable: IAuthorizable as ContractArtifact,
IERC20Bridge: IERC20Bridge as ContractArtifact,
IEth2Dai: IEth2Dai as ContractArtifact,
IUniswapExchange: IUniswapExchange as ContractArtifact,
IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact,
TestERC20Bridge: TestERC20Bridge as ContractArtifact,
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
UniswapBridge: UniswapBridge as ContractArtifact,
KyberBridge: KyberBridge as ContractArtifact,
TestStaticCallTarget: TestStaticCallTarget as ContractArtifact,
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
};

View File

@@ -13,7 +13,9 @@ import { Web3Wrapper } from '@0x/web3-wrapper';
import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import { artifacts, ERC1155ProxyContract, IAssetProxyContract } from '../../src';
import { artifacts } from './artifacts';
import { ERC1155ProxyContract, IAssetProxyContract } from './wrappers';
export class ERC1155ProxyWrapper {
private readonly _tokenOwnerAddresses: string[];
@@ -74,7 +76,7 @@ export class ERC1155ProxyWrapper {
txDefaults,
artifacts,
);
this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync();
this._proxyIdIfExists = await this._proxyContract.getProxyId().callAsync();
return this._proxyContract;
}
/**
@@ -111,19 +113,13 @@ export class ERC1155ProxyWrapper {
this._validateProxyContractExistsOrThrow();
const assetData =
assetData_ === undefined
? await this._devUtils.encodeERC1155AssetData.callAsync(
contractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
? await this._devUtils
.encodeERC1155AssetData(contractAddress, tokensToTransfer, valuesToTransfer, receiverCallbackData)
.callAsync()
: assetData_;
const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
from,
to,
valueMultiplier,
);
const data = this._assetProxyInterface
.transferFrom(assetData, from, to, valueMultiplier)
.getABIEncodedTransactionData();
return data;
}
/**
@@ -171,19 +167,13 @@ export class ERC1155ProxyWrapper {
this._validateProxyContractExistsOrThrow();
const assetData =
assetData_ === undefined
? await this._devUtils.encodeERC1155AssetData.callAsync(
contractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
? await this._devUtils
.encodeERC1155AssetData(contractAddress, tokensToTransfer, valuesToTransfer, receiverCallbackData)
.callAsync()
: assetData_;
const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
from,
to,
valueMultiplier,
);
const data = this._assetProxyInterface
.transferFrom(assetData, from, to, valueMultiplier)
.getABIEncodedTransactionData();
const txHash = await this._web3Wrapper.sendTransactionAsync({
to: (this._proxyContract as ERC1155ProxyContract).address,
data,
@@ -364,7 +354,7 @@ export class ERC1155ProxyWrapper {
this._validateProxyContractExistsOrThrow();
const tokenContract = this._getContractFromAddress(contractAddress);
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;
}
public getFungibleTokenIds(): BigNumber[] {

View File

@@ -5,7 +5,9 @@ import { BigNumber } from '@0x/utils';
import { ZeroExProvider } from 'ethereum-types';
import * as _ from 'lodash';
import { artifacts, ERC20ProxyContract } from '../../src';
import { artifacts } from './artifacts';
import { ERC20ProxyContract } from './wrappers';
export class ERC20Wrapper {
private readonly _tokenOwnerAddresses: string[];
@@ -56,7 +58,7 @@ export class ERC20Wrapper {
txDefaults,
artifacts,
);
this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync();
this._proxyIdIfExists = await this._proxyContract.getProxyId().callAsync();
return this._proxyContract;
}
public getProxyId(): string {
@@ -68,43 +70,39 @@ export class ERC20Wrapper {
this._validateProxyContractExistsOrThrow();
for (const dummyTokenContract of this._dummyTokenContracts) {
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
await dummyTokenContract.setBalance.awaitTransactionSuccessAsync(
tokenOwnerAddress,
constants.INITIAL_ERC20_BALANCE,
{ from: this._contractOwnerAddress },
);
await dummyTokenContract.approve.awaitTransactionSuccessAsync(
(this._proxyContract as ERC20ProxyContract).address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: tokenOwnerAddress },
);
await dummyTokenContract
.setBalance(tokenOwnerAddress, constants.INITIAL_ERC20_BALANCE)
.awaitTransactionSuccessAsync({ from: this._contractOwnerAddress });
await dummyTokenContract
.approve((this._proxyContract as ERC20ProxyContract).address, constants.INITIAL_ERC20_ALLOWANCE)
.awaitTransactionSuccessAsync({ from: tokenOwnerAddress });
}
}
}
public async getBalanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
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;
}
public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
await tokenContract.setBalance.awaitTransactionSuccessAsync(
userAddress,
amount,
{ from: this._contractOwnerAddress },
{ pollingIntervalMs: constants.AWAIT_TRANSACTION_MINED_MS },
);
await tokenContract
.setBalance(userAddress, amount)
.awaitTransactionSuccessAsync(
{ from: this._contractOwnerAddress },
{ pollingIntervalMs: constants.AWAIT_TRANSACTION_MINED_MS },
);
}
public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
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;
}
public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
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> {
this._validateDummyTokenContractsExistOrThrow();
@@ -113,7 +111,7 @@ export class ERC20Wrapper {
const balanceInfo: Array<{ tokenOwnerAddress: string; tokenAddress: string }> = [];
for (const dummyTokenContract of this._dummyTokenContracts) {
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
balances.push(await dummyTokenContract.balanceOf.callAsync(tokenOwnerAddress));
balances.push(await dummyTokenContract.balanceOf(tokenOwnerAddress).callAsync());
balanceInfo.push({
tokenOwnerAddress,
tokenAddress: dummyTokenContract.address,
@@ -147,7 +145,7 @@ export class ERC20Wrapper {
return tokenAddresses;
}
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);
if (tokenContractIfExists === undefined) {
throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);

View File

@@ -5,7 +5,9 @@ import { BigNumber } from '@0x/utils';
import { ZeroExProvider } from 'ethereum-types';
import * as _ from 'lodash';
import { artifacts, ERC721ProxyContract } from '../../src';
import { artifacts } from './artifacts';
import { ERC721ProxyContract } from './wrappers';
export class ERC721Wrapper {
private readonly _tokenOwnerAddresses: string[];
@@ -44,7 +46,7 @@ export class ERC721Wrapper {
txDefaults,
artifacts,
);
this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync();
this._proxyIdIfExists = await this._proxyContract.getProxyId().callAsync();
return this._proxyContract;
}
public getProxyId(): string {
@@ -78,7 +80,7 @@ export class ERC721Wrapper {
}
public async doesTokenExistAsync(tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
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;
return doesExist;
}
@@ -93,14 +95,14 @@ export class ERC721Wrapper {
): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
await tokenContract.setApprovalForAll.awaitTransactionSuccessAsync(proxyAddress, isApproved, {
await tokenContract.setApprovalForAll(proxyAddress, isApproved).awaitTransactionSuccessAsync({
from: ownerAddress,
});
}
public async approveAsync(to: string, tokenAddress: string, tokenId: BigNumber): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
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(
tokenAddress: string,
@@ -109,28 +111,28 @@ export class ERC721Wrapper {
userAddress: string,
): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
await tokenContract.transferFrom.awaitTransactionSuccessAsync(currentOwner, userAddress, tokenId, {
await tokenContract.transferFrom(currentOwner, userAddress, tokenId).awaitTransactionSuccessAsync({
from: currentOwner,
});
}
public async mintAsync(tokenAddress: string, tokenId: BigNumber, userAddress: string): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
await tokenContract.mint.awaitTransactionSuccessAsync(userAddress, tokenId, {
await tokenContract.mint(userAddress, tokenId).awaitTransactionSuccessAsync({
from: this._contractOwnerAddress,
});
}
public async burnAsync(tokenAddress: string, tokenId: BigNumber, owner: string): Promise<void> {
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> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
const owner = await tokenContract.ownerOf.callAsync(tokenId);
const owner = await tokenContract.ownerOf(tokenId).callAsync();
return owner;
}
public async isOwnerAsync(userAddress: string, tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
const tokenOwner = await tokenContract.ownerOf.callAsync(tokenId);
const tokenOwner = await tokenContract.ownerOf(tokenId).callAsync();
const isOwner = tokenOwner === userAddress;
return isOwner;
}
@@ -138,13 +140,13 @@ export class ERC721Wrapper {
this._validateProxyContractExistsOrThrow();
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
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;
}
public async isProxyApprovedAsync(tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
this._validateProxyContractExistsOrThrow();
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 isProxyAnApprovedOperator = approvedAddress === proxyAddress;
return isProxyAnApprovedOperator;
@@ -161,7 +163,7 @@ export class ERC721Wrapper {
dummyTokenContract.address
];
for (const tokenId of initialTokenOwnerIds) {
tokenOwnerAddresses.push(await dummyTokenContract.ownerOf.callAsync(tokenId));
tokenOwnerAddresses.push(await dummyTokenContract.ownerOf(tokenId).callAsync());
tokenInfo.push({
tokenId,
tokenAddress: dummyTokenContract.address,

View File

@@ -1,3 +1,64 @@
export * from './artifacts';
export * from './wrappers';
export * from '../test/utils';
export { artifacts } from './artifacts';
export {
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';

View File

@@ -10,19 +10,8 @@ export * from '../generated-wrappers/erc721_proxy';
export * from '../generated-wrappers/eth2_dai_bridge';
export * from '../generated-wrappers/i_asset_data';
export * from '../generated-wrappers/i_asset_proxy';
export * from '../generated-wrappers/i_asset_proxy_dispatcher';
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/kyber_bridge';
export * from '../generated-wrappers/multi_asset_proxy';
export * from '../generated-wrappers/ownable';
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_uniswap_bridge';
export * from '../generated-wrappers/uniswap_bridge';

View File

@@ -0,0 +1,61 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
import { ContractArtifact } from 'ethereum-types';
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 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 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,
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,
IERC20Bridge: IERC20Bridge as ContractArtifact,
IEth2Dai: IEth2Dai as ContractArtifact,
IKyberNetworkProxy: IKyberNetworkProxy as ContractArtifact,
IUniswapExchange: IUniswapExchange as ContractArtifact,
IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact,
TestERC20Bridge: TestERC20Bridge as ContractArtifact,
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
TestKyberBridge: TestKyberBridge as ContractArtifact,
TestStaticCallTarget: TestStaticCallTarget as ContractArtifact,
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
};

View File

@@ -5,7 +5,9 @@ import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
import { artifacts, MixinAuthorizableContract } from '../src';
import { artifacts } from './artifacts';
import { MixinAuthorizableContract } from './wrappers';
chaiSetup.configure();
const expect = chai.expect;
@@ -47,21 +49,21 @@ describe('Authorizable', () => {
describe('addAuthorizedAddress', () => {
it('should revert if not called by owner', async () => {
await expectTransactionFailedAsync(
authorizable.addAuthorizedAddress.sendTransactionAsync(notOwner, { from: notOwner }),
authorizable.addAuthorizedAddress(notOwner).sendTransactionAsync({ from: notOwner }),
RevertReason.OnlyContractOwner,
);
});
it('should allow owner to add an authorized address', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const isAuthorized = await authorizable.authorized.callAsync(address);
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
const isAuthorized = await authorizable.authorized(address).callAsync();
expect(isAuthorized).to.be.true();
});
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(
authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
authorizable.addAuthorizedAddress(address).sendTransactionAsync({ from: owner }),
RevertReason.TargetAlreadyAuthorized,
);
});
@@ -69,23 +71,23 @@ describe('Authorizable', () => {
describe('removeAuthorizedAddress', () => {
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(
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { from: notOwner }),
authorizable.removeAuthorizedAddress(address).sendTransactionAsync({ from: notOwner }),
RevertReason.OnlyContractOwner,
);
});
it('should allow owner to remove an authorized address', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const isAuthorized = await authorizable.authorized.callAsync(address);
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
await authorizable.removeAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
const isAuthorized = await authorizable.authorized(address).callAsync();
expect(isAuthorized).to.be.false();
});
it('should revert if owner attempts to remove an address that is not authorized', async () => {
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
authorizable.removeAuthorizedAddress(address).sendTransactionAsync({
from: owner,
}),
RevertReason.TargetNotAuthorized,
@@ -95,10 +97,10 @@ describe('Authorizable', () => {
describe('removeAuthorizedAddressAtIndex', () => {
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);
await expectTransactionFailedAsync(
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
authorizable.removeAuthorizedAddressAtIndex(address, index).sendTransactionAsync({
from: notOwner,
}),
RevertReason.OnlyContractOwner,
@@ -106,10 +108,10 @@ describe('Authorizable', () => {
});
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);
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
authorizable.removeAuthorizedAddressAtIndex(address, index).sendTransactionAsync({
from: owner,
}),
RevertReason.IndexOutOfBounds,
@@ -119,7 +121,7 @@ describe('Authorizable', () => {
it('should revert if owner attempts to remove an address that is not authorized', async () => {
const index = new BigNumber(0);
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
authorizable.removeAuthorizedAddressAtIndex(address, index).sendTransactionAsync({
from: owner,
}),
RevertReason.TargetNotAuthorized,
@@ -129,11 +131,11 @@ describe('Authorizable', () => {
it('should revert if address at index does not match target', async () => {
const address1 = address;
const address2 = notOwner;
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address1, { from: owner });
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address2, { from: owner });
await authorizable.addAuthorizedAddress(address1).awaitTransactionSuccessAsync({ from: owner });
await authorizable.addAuthorizedAddress(address2).awaitTransactionSuccessAsync({ from: owner });
const address1Index = new BigNumber(0);
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address2, address1Index, {
authorizable.removeAuthorizedAddressAtIndex(address2, address1Index).sendTransactionAsync({
from: owner,
}),
RevertReason.AuthorizedAddressMismatch,
@@ -141,26 +143,26 @@ describe('Authorizable', () => {
});
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);
await authorizable.removeAuthorizedAddressAtIndex.awaitTransactionSuccessAsync(address, index, {
await authorizable.removeAuthorizedAddressAtIndex(address, index).awaitTransactionSuccessAsync({
from: owner,
});
const isAuthorized = await authorizable.authorized.callAsync(address);
const isAuthorized = await authorizable.authorized(address).callAsync();
expect(isAuthorized).to.be.false();
});
});
describe('getAuthorizedAddresses', () => {
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);
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const afterAdd = await authorizable.getAuthorizedAddresses.callAsync();
await authorizable.addAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
const afterAdd = await authorizable.getAuthorizedAddresses().callAsync();
expect(afterAdd).to.have.length(1);
expect(afterAdd).to.include(address);
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const afterRemove = await authorizable.getAuthorizedAddresses.callAsync();
await authorizable.removeAuthorizedAddress(address).awaitTransactionSuccessAsync({ from: owner });
const afterRemove = await authorizable.getAuthorizedAddresses().callAsync();
expect(afterRemove).to.have.length(0);
});
});

View File

@@ -15,15 +15,19 @@ import {
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { SafeMathRevertErrors } from '@0x/contracts-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { AssetProxyId, RevertReason } from '@0x/types';
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types';
import * as ethUtil from 'ethereumjs-util';
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();
const expect = chai.expect;
@@ -74,8 +78,8 @@ describe('ERC1155Proxy', () => {
const usedAddresses = ([owner, notAuthorized, authorized, spender, receiver] = _.slice(accounts, 0, 5));
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(authorized, { from: owner });
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(erc1155Proxy.address, { from: owner });
await erc1155Proxy.addAuthorizedAddress(authorized).awaitTransactionSuccessAsync({ from: owner });
await erc1155Proxy.addAuthorizedAddress(erc1155Proxy.address).awaitTransactionSuccessAsync({ from: owner });
// deploy & configure ERC1155 tokens and receiver
[erc1155Wrapper] = await erc1155ProxyWrapper.deployDummyContractsAsync();
erc1155Contract = erc1155Wrapper.getContract();
@@ -119,7 +123,7 @@ describe('ERC1155Proxy', () => {
);
});
it('should have an id of 0xa7cb5fb7', async () => {
const proxyId = await erc1155Proxy.getProxyId.callAsync();
const proxyId = await erc1155Proxy.getProxyId().callAsync();
const expectedProxyId = AssetProxyId.ERC1155;
expect(proxyId).to.equal(expectedProxyId);
});
@@ -634,12 +638,14 @@ describe('ERC1155Proxy', () => {
return value.times(valueMultiplier);
});
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
const extraData = '0102030405060708091001020304050607080910010203040506070809100102';
const assetDataWithExtraData = `${assetData}${extraData}`;
// check balances before transfer
@@ -694,14 +700,16 @@ describe('ERC1155Proxy', () => {
// create token
await erc1155Wrapper
.getContract()
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
.createWithType(tokenToCreate, tokenUri)
.awaitTransactionSuccessAsync({
from: owner,
});
// mint balance for spender
await erc1155Wrapper
.getContract()
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
.mintFungible(tokenToCreate, [spender], [spenderInitialBalance])
.awaitTransactionSuccessAsync({
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
const assetDataContract = new IAssetDataContract(constants.NULL_ADDRESS, provider);
const selector = assetDataContract.ERC1155Assets.getSelector();
const selector = assetDataContract.getSelector('ERC1155Assets');
const assetDataWithoutContractAddress =
'0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040102030400000000000000000000000000000000000000000000000000000000';
const assetData = `${selector}000000000000000000000000${erc1155ContractAddress.substr(
@@ -794,14 +802,16 @@ describe('ERC1155Proxy', () => {
// create token
await erc1155Wrapper
.getContract()
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
.createWithType(tokenToCreate, tokenUri)
.awaitTransactionSuccessAsync({
from: owner,
});
// mint balance for spender
await erc1155Wrapper
.getContract()
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
.mintFungible(tokenToCreate, [spender], [spenderInitialBalance])
.awaitTransactionSuccessAsync({
from: owner,
});
}
@@ -847,12 +857,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [new BigNumber(2), new BigNumber(2)];
const valueMultiplier = new BigNumber(2);
// create callback data that is the encoded version of `valuesToTransfer`
const generatedAssetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const generatedAssetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// remove the function selector and contract address from check, as these change on each test
const offsetToTokenIds = 74;
const assetDataSelectorAndContractAddress = generatedAssetData.substr(0, offsetToTokenIds);
@@ -919,14 +931,16 @@ describe('ERC1155Proxy', () => {
// create token
await erc1155Wrapper
.getContract()
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
.createWithType(tokenToCreate, tokenUri)
.awaitTransactionSuccessAsync({
from: owner,
});
// mint balance for spender
await erc1155Wrapper
.getContract()
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
.mintFungible(tokenToCreate, [spender], [spenderInitialBalance])
.awaitTransactionSuccessAsync({
from: owner,
});
}
@@ -969,12 +983,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [new BigNumber(1), new BigNumber(2)];
const valueMultiplier = new BigNumber(2);
// create callback data that is the encoded version of `valuesToTransfer`
const generatedAssetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const generatedAssetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// remove the function selector and contract address from check, as these change on each test
const offsetToTokenIds = 74;
const assetDataSelectorAndContractAddress = generatedAssetData.substr(0, offsetToTokenIds);
@@ -1032,12 +1048,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1079,12 +1097,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1130,12 +1150,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1181,12 +1203,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1232,12 +1256,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1284,12 +1310,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1331,12 +1359,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1382,12 +1412,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1429,12 +1461,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
// The asset data we just generated will look like this:
// a7cb5fb7
// 0x 0000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082
@@ -1480,12 +1514,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync(
spender,
receiverContract,
@@ -1511,12 +1547,14 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const assetData = await devUtils
.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
.callAsync();
const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync(
spender,
receiverContract,
@@ -1640,7 +1678,7 @@ describe('ERC1155Proxy', () => {
it('should propagate revert reason from erc1155 contract failure', async () => {
// disable transfers
const shouldRejectTransfer = true;
await erc1155Receiver.setRejectTransferFlag.awaitTransactionSuccessAsync(shouldRejectTransfer, {
await erc1155Receiver.setRejectTransferFlag(shouldRejectTransfer).awaitTransactionSuccessAsync({
from: owner,
});
// setup test parameters

View File

@@ -9,17 +9,15 @@ import {
Numberish,
randomAddress,
} from '@0x/contracts-test-utils';
import { AuthorizableRevertErrors } from '@0x/contracts-utils';
import { AssetProxyId } from '@0x/types';
import { AbiEncoder, AuthorizableRevertErrors, BigNumber, StringRevertError } from '@0x/utils';
import { AbiEncoder, BigNumber, StringRevertError } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import {
artifacts,
ERC20BridgeProxyContract,
TestERC20BridgeBridgeWithdrawToEventArgs,
TestERC20BridgeContract,
} from '../src';
import { artifacts } from './artifacts';
import { ERC20BridgeProxyContract, TestERC20BridgeContract } from './wrappers';
blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
const PROXY_ID = AssetProxyId.ERC20Bridge;
@@ -44,8 +42,8 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
env.txDefaults,
artifacts,
);
testTokenAddress = await bridgeContract.testToken.callAsync();
await assetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(owner);
testTokenAddress = await bridgeContract.testToken().callAsync();
await assetProxy.addAuthorizedAddress(owner).awaitTransactionSuccessAsync();
});
interface AssetDataOpts {
@@ -102,7 +100,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
}
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()', () => {
@@ -132,13 +130,9 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
async function transferFromAsync(opts?: Partial<TransferFromOpts>, caller?: string): Promise<DecodedLogs> {
const _opts = createTransferFromOpts(opts);
const { logs } = await assetProxy.transferFrom.awaitTransactionSuccessAsync(
encodeAssetData(_opts.assetData),
_opts.from,
_opts.to,
new BigNumber(_opts.amount),
{ from: caller },
);
const { logs } = await assetProxy
.transferFrom(encodeAssetData(_opts.assetData), _opts.from, _opts.to, new BigNumber(_opts.amount))
.awaitTransactionSuccessAsync({ from: caller });
return (logs as any) as DecodedLogs;
}
@@ -164,7 +158,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
const opts = createTransferFromOpts();
const logs = await transferFromAsync(opts);
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.from).to.eq(opts.from);
expect(args.to).to.eq(opts.to);
@@ -180,12 +174,9 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
it('fails if asset data is truncated', async () => {
const opts = createTransferFromOpts();
const truncatedAssetData = hexSlice(encodeAssetData(opts.assetData), 0, -1);
const tx = assetProxy.transferFrom.awaitTransactionSuccessAsync(
truncatedAssetData,
opts.from,
opts.to,
new BigNumber(opts.amount),
);
const tx = assetProxy
.transferFrom(truncatedAssetData, opts.from, opts.to, new BigNumber(opts.amount))
.awaitTransactionSuccessAsync();
return expect(tx).to.be.rejected();
});
@@ -281,18 +272,18 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
it('retrieves the balance of the encoded token', async () => {
const _owner = randomAddress();
const balance = getRandomInteger(1, 100e18);
await bridgeContract.setTestTokenBalance.awaitTransactionSuccessAsync(_owner, balance);
await bridgeContract.setTestTokenBalance(_owner, balance).awaitTransactionSuccessAsync();
const assetData = createAssetData({
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);
});
});
describe('getProxyId()', () => {
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);
});
});

View File

@@ -8,24 +8,23 @@ import {
hexRandom,
Numberish,
randomAddress,
TransactionHelper,
} from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types';
import { BigNumber, RawRevertError } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import { artifacts } from './artifacts';
import {
artifacts,
TestEth2DaiBridgeContract,
TestEth2DaiBridgeEvents,
TestEth2DaiBridgeSellAllAmountEventArgs,
TestEth2DaiBridgeTokenApproveEventArgs,
TestEth2DaiBridgeTokenTransferEventArgs,
} from '../src';
} from './wrappers';
blockchainTests.resets('Eth2DaiBridge unit tests', env => {
const txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
let testContract: TestEth2DaiBridgeContract;
before(async () => {
@@ -40,7 +39,7 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => {
describe('isValidSignature()', () => {
it('returns success bytes', async () => {
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
const result = await testContract.isValidSignature.callAsync(hexRandom(), hexRandom(_.random(0, 32)));
const result = await testContract.isValidSignature(hexRandom(), hexRandom(_.random(0, 32))).callAsync();
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
});
});
@@ -80,32 +79,30 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => {
async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> {
const _opts = createWithdrawToOpts(opts);
// Set the fill behavior.
await testContract.setFillBehavior.awaitTransactionSuccessAsync(
_opts.revertReason,
new BigNumber(_opts.fillAmount),
);
await testContract
.setFillBehavior(_opts.revertReason, new BigNumber(_opts.fillAmount))
.awaitTransactionSuccessAsync();
// Create tokens and balances.
if (_opts.fromTokenAddress === undefined) {
[_opts.fromTokenAddress] = await txHelper.getResultAndReceiptAsync(
testContract.createToken,
new BigNumber(_opts.fromTokenBalance),
);
const createTokenFn = testContract.createToken(new BigNumber(_opts.fromTokenBalance));
_opts.fromTokenAddress = await createTokenFn.callAsync();
await createTokenFn.awaitTransactionSuccessAsync();
}
if (_opts.toTokenAddress === undefined) {
[_opts.toTokenAddress] = await txHelper.getResultAndReceiptAsync(
testContract.createToken,
constants.ZERO_AMOUNT,
);
const createTokenFn = testContract.createToken(constants.ZERO_AMOUNT);
_opts.toTokenAddress = await createTokenFn.callAsync();
await createTokenFn.awaitTransactionSuccessAsync();
}
// Set the transfer behavior of `toTokenAddress`.
await testContract.setTransferBehavior.awaitTransactionSuccessAsync(
_opts.toTokenAddress,
_opts.toTokentransferRevertReason,
_opts.toTokenTransferReturnData,
);
await testContract
.setTransferBehavior(
_opts.toTokenAddress,
_opts.toTokentransferRevertReason,
_opts.toTokenTransferReturnData,
)
.awaitTransactionSuccessAsync();
// Call bridgeTransferFrom().
const [result, { logs }] = await txHelper.getResultAndReceiptAsync(
testContract.bridgeTransferFrom,
const bridgeTransferFromFn = testContract.bridgeTransferFrom(
// "to" token address
_opts.toTokenAddress,
// Random from address.
@@ -116,6 +113,8 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => {
// ABI-encode the "from" token address as the bridge data.
hexLeftPad(_opts.fromTokenAddress as string),
);
const result = await bridgeTransferFromFn.callAsync();
const { logs } = await bridgeTransferFromFn.awaitTransactionSuccessAsync();
return {
opts: _opts,
result,

View File

@@ -0,0 +1,272 @@
import {
blockchainTests,
constants,
expect,
getRandomInteger,
hexLeftPad,
hexRandom,
randomAddress,
verifyEventsFromLogs,
} from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types';
import { BigNumber } 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(hexRandom(), hexRandom(_.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.
hexLeftPad(_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

View File

@@ -14,7 +14,9 @@ import { AbiEncoder, BigNumber } from '@0x/utils';
import * as chai from 'chai';
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();
const expect = chai.expect;
@@ -79,26 +81,21 @@ describe('StaticCallProxy', () => {
);
});
it('should have an id of 0xc339d10a', async () => {
const proxyId = await staticCallProxy.getProxyId.callAsync();
const proxyId = await staticCallProxy.getProxyId().callAsync();
const expectedProxyId = AssetProxyId.StaticCall;
expect(proxyId).to.equal(expectedProxyId);
});
});
describe('transferFrom', () => {
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 assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const txData = staticCallProxy.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
toAddress,
amount,
);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
const txData = staticCallProxy
.transferFrom(assetData, fromAddress, toAddress, amount)
.getABIEncodedTransactionData();
const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080';
const txDataEndBuffer = ethUtil.toBuffer((txData.length - 2) / 2 - 4);
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 () => {
const staticCallData = constants.NULL_BYTES;
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = (await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
)).slice(0, -128);
const assetData = (await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync()).slice(0, -128);
const assetDataByteLen = (assetData.length - 2) / 2;
expect((assetDataByteLen - 4) % 32).to.equal(0);
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 () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
const staticCallData = staticCallTarget.noInputFunction().getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
const offsetToStaticCallData = '0000000000000000000000000000000000000000000000000000000000000060';
const assetDataEndBuffer = ethUtil.toBuffer((assetData.length - 2) / 2 - 4);
const paddedAssetDataEndBuffer = ethUtil.setLengthLeft(assetDataEndBuffer, 32);
@@ -145,94 +138,88 @@ describe('StaticCallProxy', () => {
invalidOffsetToStaticCallData,
)}${newStaticCallData}`;
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 () => {
const staticCallData = staticCallTarget.updateState.getABIEncodedTransactionData();
const staticCallData = staticCallTarget.updateState().getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
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 () => {
const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1));
const staticCallData = staticCallTarget.assertEvenNumber(new BigNumber(1)).getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
RevertReason.TargetNotEven,
);
});
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 expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
RevertReason.UnexpectedStaticCallResult,
);
});
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 assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
await staticCallProxy
.transferFrom(assetData, fromAddress, toAddress, amount)
.awaitTransactionSuccessAsync();
});
it('should be successful if the staticCallTarget is not a contract and no return value is expected', async () => {
const staticCallData = '0x0102030405060708';
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
toAddress,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
const assetData = await devUtils
.encodeStaticCallAssetData(toAddress, staticCallData, expectedResultHash)
.callAsync();
await staticCallProxy
.transferFrom(assetData, fromAddress, toAddress, amount)
.awaitTransactionSuccessAsync();
});
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 expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
await staticCallProxy
.transferFrom(assetData, fromAddress, toAddress, amount)
.awaitTransactionSuccessAsync();
});
it('should be successful if a function with one dynamic input is successful', async () => {
const dynamicInput = '0x0102030405060708';
const staticCallData = staticCallTarget.dynamicInputFunction.getABIEncodedTransactionData(dynamicInput);
const staticCallData = staticCallTarget.dynamicInputFunction(dynamicInput).getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
await staticCallProxy
.transferFrom(assetData, fromAddress, toAddress, amount)
.awaitTransactionSuccessAsync();
});
it('should be successful if a function call returns a complex type', async () => {
const a = new BigNumber(1);
const b = new BigNumber(2);
const staticCallData = staticCallTarget.returnComplexType.getABIEncodedTransactionData(a, b);
const staticCallData = staticCallTarget.returnComplexType(a, b).getABIEncodedTransactionData();
const abiEncoder = new AbiEncoder.DynamicBytes({
name: '',
type: 'bytes',
@@ -245,12 +232,12 @@ describe('StaticCallProxy', () => {
const expectedResultHash = ethUtil.bufferToHex(
ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)),
);
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
const assetData = await devUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.callAsync();
await staticCallProxy
.transferFrom(assetData, fromAddress, toAddress, amount)
.awaitTransactionSuccessAsync();
});
});
});

View File

@@ -9,15 +9,15 @@ import {
hexRandom,
Numberish,
randomAddress,
TransactionHelper,
} from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import { artifacts } from './artifacts';
import {
artifacts,
TestUniswapBridgeContract,
TestUniswapBridgeEthToTokenTransferInputEventArgs as EthToTokenTransferInputArgs,
TestUniswapBridgeEvents as ContractEvents,
@@ -27,10 +27,9 @@ import {
TestUniswapBridgeTokenTransferEventArgs as TokenTransferArgs,
TestUniswapBridgeWethDepositEventArgs as WethDepositArgs,
TestUniswapBridgeWethWithdrawEventArgs as WethWithdrawArgs,
} from '../src';
} from './wrappers';
blockchainTests.resets('UniswapBridge unit tests', env => {
const txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
let testContract: TestUniswapBridgeContract;
let wethTokenAddress: string;
@@ -41,13 +40,13 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
env.txDefaults,
artifacts,
);
wethTokenAddress = await testContract.wethToken.callAsync();
wethTokenAddress = await testContract.wethToken().callAsync();
});
describe('isValidSignature()', () => {
it('returns success bytes', async () => {
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
const result = await testContract.isValidSignature.callAsync(hexRandom(), hexRandom(_.random(0, 32)));
const result = await testContract.isValidSignature(hexRandom(), hexRandom(_.random(0, 32))).callAsync();
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> {
const _opts = createWithdrawToOpts(opts);
const callData = { value: new BigNumber(_opts.exchangeFillAmount) };
// Create the "from" token and exchange.
[[_opts.fromTokenAddress]] = await txHelper.getResultAndReceiptAsync(
testContract.createTokenAndExchange,
const createFromTokenFn = testContract.createTokenAndExchange(
_opts.fromTokenAddress,
_opts.exchangeRevertReason,
{ value: new BigNumber(_opts.exchangeFillAmount) },
);
[_opts.fromTokenAddress] = await createFromTokenFn.callAsync(callData);
await createFromTokenFn.awaitTransactionSuccessAsync(callData);
// Create the "to" token and exchange.
[[_opts.toTokenAddress]] = await txHelper.getResultAndReceiptAsync(
testContract.createTokenAndExchange,
const createToTokenFn = testContract.createTokenAndExchange(
_opts.toTokenAddress,
_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.
await testContract.setTokenBalance.awaitTransactionSuccessAsync(_opts.fromTokenAddress, {
await testContract.setTokenBalance(_opts.fromTokenAddress).awaitTransactionSuccessAsync({
value: new BigNumber(_opts.fromTokenBalance),
});
// Call bridgeTransferFrom().
const [result, receipt] = await txHelper.getResultAndReceiptAsync(
testContract.bridgeTransferFrom,
const bridgeTransferFromFn = testContract.bridgeTransferFrom(
// The "to" token address.
_opts.toTokenAddress,
// The "from" address.
@@ -129,6 +128,8 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
// ABI-encoded "from" token address.
hexLeftPad(_opts.fromTokenAddress),
);
const result = await bridgeTransferFromFn.callAsync();
const receipt = await bridgeTransferFromFn.awaitTransactionSuccessAsync();
return {
opts: _opts,
result,
@@ -138,7 +139,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
}
async function getExchangeForTokenAsync(tokenAddress: string): Promise<string> {
return testContract.getExchange.callAsync(tokenAddress);
return testContract.getExchange(tokenAddress).callAsync();
}
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 () => {
const [[tokenAddress]] = await txHelper.getResultAndReceiptAsync(
testContract.createTokenAndExchange,
constants.NULL_ADDRESS,
'',
);
const createTokenFn = await testContract.createTokenAndExchange(constants.NULL_ADDRESS, '');
const [tokenAddress] = await createTokenFn.callAsync();
await createTokenFn.awaitTransactionSuccessAsync();
const { opts, result, logs } = await withdrawToAsync({
fromTokenAddress: tokenAddress,
toTokenAddress: tokenAddress,
@@ -203,14 +202,16 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
});
it('fails if "from" token does not exist', async () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
randomAddress(),
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(randomAddress()),
);
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
const tx = testContract
.bridgeTransferFrom(
randomAddress(),
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(randomAddress()),
)
.awaitTransactionSuccessAsync();
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
});
it('fails if the exchange fails', async () => {
@@ -218,7 +219,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
const tx = withdrawToAsync({
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 () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
randomAddress(),
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(wethTokenAddress),
);
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
const tx = testContract
.bridgeTransferFrom(
randomAddress(),
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(wethTokenAddress),
)
.awaitTransactionSuccessAsync();
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
});
it('fails if `WETH.deposit()` fails', async () => {
@@ -291,7 +294,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
toTokenAddress: wethTokenAddress,
toTokenRevertReason: revertReason,
});
return expect(tx).to.revertWith(revertReason);
return expect(tx).to.eventually.be.rejectedWith(revertReason);
});
it('fails if the exchange fails', async () => {
@@ -300,7 +303,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
toTokenAddress: wethTokenAddress,
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 () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
wethTokenAddress,
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(randomAddress()),
);
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
const tx = testContract
.bridgeTransferFrom(
wethTokenAddress,
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(randomAddress()),
)
.awaitTransactionSuccessAsync();
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
});
it('fails if the `WETH.withdraw()` fails', async () => {
@@ -349,7 +354,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
fromTokenAddress: wethTokenAddress,
fromTokenRevertReason: revertReason,
});
return expect(tx).to.revertWith(revertReason);
return expect(tx).to.eventually.be.rejectedWith(revertReason);
});
it('fails if the exchange fails', async () => {
@@ -358,7 +363,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
fromTokenAddress: wethTokenAddress,
exchangeRevertReason: revertReason,
});
return expect(tx).to.revertWith(revertReason);
return expect(tx).to.eventually.be.rejectedWith(revertReason);
});
});
});

View File

@@ -1,3 +0,0 @@
export * from './erc20_wrapper';
export * from './erc721_wrapper';
export * from './erc1155_proxy_wrapper';

View File

@@ -0,0 +1,31 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
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_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_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';

View File

@@ -10,22 +10,37 @@
"generated-artifacts/Eth2DaiBridge.json",
"generated-artifacts/IAssetData.json",
"generated-artifacts/IAssetProxy.json",
"generated-artifacts/IAssetProxyDispatcher.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/KyberBridge.json",
"generated-artifacts/MultiAssetProxy.json",
"generated-artifacts/Ownable.json",
"generated-artifacts/StaticCallProxy.json",
"generated-artifacts/TestERC20Bridge.json",
"generated-artifacts/TestEth2DaiBridge.json",
"generated-artifacts/TestStaticCallTarget.json",
"generated-artifacts/TestUniswapBridge.json",
"generated-artifacts/UniswapBridge.json"
"generated-artifacts/UniswapBridge.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/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/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"]
}

View 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

View File

@@ -1,4 +1,98 @@
[
{
"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",
"changes": [

View File

@@ -5,6 +5,36 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## 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_
* Dependencies updated

View File

@@ -1,5 +1,5 @@
{
"artifactsDir": "./generated-artifacts",
"artifactsDir": "./test/generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": false,
"compilerSettings": {

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-coordinator",
"version": "2.1.0-beta.1",
"version": "3.0.0",
"engines": {
"node": ">=6.12"
},
@@ -12,7 +12,7 @@
"scripts": {
"build": "yarn pre_build && tsc -b",
"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",
"rebuild_and_test": "run-s build test",
"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",
"compile": "sol-compiler",
"watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"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 test/generated-wrappers --backend ethers",
"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 ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage: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",
"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",
"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": {
"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."
},
"repository": {
@@ -48,17 +52,19 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
"devDependencies": {
"@0x/abi-gen": "^4.4.0-beta.1",
"@0x/contracts-asset-proxy": "^2.3.0-beta.1",
"@0x/contracts-dev-utils": "^0.1.0-beta.1",
"@0x/contracts-erc20": "^2.3.0-beta.1",
"@0x/contracts-exchange": "^2.2.0-beta.1",
"@0x/contracts-gen": "^1.1.0-beta.1",
"@0x/contracts-test-utils": "^3.2.0-beta.1",
"@0x/dev-utils": "^2.4.0-beta.1",
"@0x/order-utils": "^8.5.0-beta.1",
"@0x/sol-compiler": "^3.2.0-beta.1",
"@0x/tslint-config": "^3.1.0-beta.1",
"@0x/abi-gen": "^5.0.0",
"@0x/contracts-asset-proxy": "^3.0.0",
"@0x/contracts-dev-utils": "^1.0.0",
"@0x/contracts-erc20": "^3.0.0",
"@0x/contracts-exchange": "^3.0.0",
"@0x/contracts-gen": "^2.0.0",
"@0x/contracts-test-utils": "^4.0.0",
"@0x/dev-utils": "^3.0.0",
"@0x/order-utils": "^9.0.0",
"@0x/sol-compiler": "^4.0.0",
"@0x/ts-doc-gen": "^0.0.22",
"@0x/tslint-config": "^4.0.0",
"@0x/web3-wrapper": "^7.0.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "*",
@@ -74,16 +80,20 @@
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typedoc": "^0.15.0",
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.5.0-beta.1",
"@0x/types": "^2.5.0-beta.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",
"ethereumjs-util": "^5.1.1"
"@0x/assert": "^3.0.0",
"@0x/base-contract": "^6.0.0",
"@0x/contract-addresses": "^4.0.0",
"@0x/contracts-utils": "^4.0.0",
"@0x/json-schemas": "^5.0.0",
"@0x/types": "^3.0.0",
"@0x/typescript-typings": "^5.0.0",
"@0x/utils": "^5.0.0",
"ethereum-types": "^3.0.0",
"http-status-codes": "^1.3.2"
},
"publishConfig": {
"access": "public"

View File

@@ -1,7 +1,8 @@
import { hexConcat, signingUtils } from '@0x/contracts-test-utils';
import { SignatureType, SignedZeroExTransaction } from '@0x/types';
import { hashUtils, SignedCoordinatorApproval } from './index';
import { hashUtils } from './hash_utils';
import { SignedCoordinatorApproval } from './types';
export class ApprovalFactory {
private readonly _privateKey: Buffer;
@@ -12,12 +13,16 @@ export class ApprovalFactory {
this._verifyingContractAddress = verifyingContract;
}
public newSignedApproval(
public async newSignedApprovalAsync(
transaction: SignedZeroExTransaction,
txOrigin: string,
signatureType: SignatureType = SignatureType.EthSign,
): SignedCoordinatorApproval {
const approvalHashBuff = hashUtils.getApprovalHashBuffer(transaction, this._verifyingContractAddress, txOrigin);
): Promise<SignedCoordinatorApproval> {
const approvalHashBuff = await hashUtils.getApprovalHashBufferAsync(
transaction,
this._verifyingContractAddress,
txOrigin,
);
const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType);
const signedApproval = {
txOrigin,

View File

@@ -7,31 +7,15 @@ import { ContractArtifact } from 'ethereum-types';
import * as Coordinator from '../generated-artifacts/Coordinator.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 LibCoordinatorApproval from '../generated-artifacts/LibCoordinatorApproval.json';
import * as LibCoordinatorRichErrors from '../generated-artifacts/LibCoordinatorRichErrors.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 = {
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,
CoordinatorRegistry: CoordinatorRegistry 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,
LibConstants: LibConstants as ContractArtifact,
};

View 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

View File

@@ -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 { BigNumber } from '@0x/utils'; // tslint:disable-line:no-unused-variable
import { Web3Wrapper } from '@0x/web3-wrapper';
import * as _ from 'lodash';
export const assert = {
...sharedAssert,

View File

@@ -2,10 +2,6 @@ import { Order, SignedOrder, SignedZeroExTransaction } from '@0x/types';
import { BigNumber } from '@0x/utils';
export interface CoordinatorServerApprovalResponse {
signatures: string[];
expirationTimeSeconds: BigNumber[];
}
export interface CoordinatorServerApprovalRawResponse {
signatures: string[];
expirationTimeSeconds: BigNumber;
}
@@ -24,7 +20,7 @@ export interface CoordinatorOutstandingFillSignatures {
export interface CoordinatorServerResponse {
isError: boolean;
status: number;
body?: CoordinatorServerCancellationResponse | CoordinatorServerApprovalRawResponse;
body?: CoordinatorServerCancellationResponse | CoordinatorServerApprovalResponse;
error?: any;
request: CoordinatorServerRequest;
coordinatorOperator: string;
@@ -38,12 +34,12 @@ export interface CoordinatorServerRequest {
export class CoordinatorServerError extends Error {
public message: CoordinatorServerErrorMsg;
public approvedOrders?: SignedOrder[] = [];
public approvedOrders?: Order[] = [];
public cancellations?: CoordinatorServerCancellationResponse[] = [];
public errors: CoordinatorServerResponse[];
constructor(
message: CoordinatorServerErrorMsg,
approvedOrders: SignedOrder[],
approvedOrders: Order[],
cancellations: CoordinatorServerCancellationResponse[],
errors: CoordinatorServerResponse[],
) {

View File

@@ -0,0 +1,28 @@
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 = {
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 = hexConcat(await hashUtils.getApprovalHashBufferAsync(transaction, verifyingContract, txOrigin));
return hashHex;
},
};

View File

@@ -1,3 +1,66 @@
export * from './artifacts';
export * from './wrappers';
export * from '../test/utils';
export { artifacts } from './artifacts';
export {
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';

View File

@@ -1,4 +1,5 @@
import { SignedZeroExTransaction } from '@0x/types';
import { BigNumber } from '@0x/utils';
export interface CoordinatorApproval {
transaction: SignedZeroExTransaction;
@@ -8,3 +9,9 @@ export interface CoordinatorApproval {
export interface SignedCoordinatorApproval extends CoordinatorApproval {
signature: string;
}
export interface CoordinatorTransaction {
salt: BigNumber;
signerAddress: string;
data: string;
}

View File

@@ -5,15 +5,7 @@
*/
export * from '../generated-wrappers/coordinator';
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_coordinator_approval';
export * from '../generated-wrappers/lib_coordinator_rich_errors';
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';

View 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,
};

View File

@@ -1,6 +1,8 @@
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
blockchainTests.resets('Coordinator Registry tests', env => {
@@ -23,43 +25,42 @@ blockchainTests.resets('Coordinator Registry tests', env => {
});
describe('core', () => {
it('Should successfully set a Coordinator endpoint', async () => {
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, {
await coordinatorRegistry.setCoordinatorEndpoint(coordinatorEndpoint).awaitTransactionSuccessAsync({
from: coordinatorOperator,
});
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
const recordedCoordinatorEndpoint = await coordinatorRegistry
.getCoordinatorEndpoint(coordinatorOperator)
.callAsync();
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
});
it('Should successfully unset a Coordinator endpoint', async () => {
// set Coordinator endpoint
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, {
await coordinatorRegistry.setCoordinatorEndpoint(coordinatorEndpoint).awaitTransactionSuccessAsync({
from: coordinatorOperator,
});
let recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
let recordedCoordinatorEndpoint = await coordinatorRegistry
.getCoordinatorEndpoint(coordinatorOperator)
.callAsync();
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
// unset Coordinator endpoint
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(nilCoordinatorEndpoint, {
await coordinatorRegistry.setCoordinatorEndpoint(nilCoordinatorEndpoint).awaitTransactionSuccessAsync({
from: coordinatorOperator,
});
recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
recordedCoordinatorEndpoint = await coordinatorRegistry
.getCoordinatorEndpoint(coordinatorOperator)
.callAsync();
expect(recordedCoordinatorEndpoint).to.be.equal(nilCoordinatorEndpoint);
});
it('Should emit an event when setting Coordinator endpoint', async () => {
// set Coordinator endpoint
const txReceipt = await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(
coordinatorEndpoint,
{
const txReceipt = await coordinatorRegistry
.setCoordinatorEndpoint(coordinatorEndpoint)
.awaitTransactionSuccessAsync({
from: coordinatorOperator,
},
);
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
});
const recordedCoordinatorEndpoint = await coordinatorRegistry
.getCoordinatorEndpoint(coordinatorOperator)
.callAsync();
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
// validate event
const expectedEvent: CoordinatorRegistryCoordinatorEndpointSetEventArgs = {

View File

@@ -1,8 +1,11 @@
import { blockchainTests, constants, expect, randomAddress } from '@0x/contracts-test-utils';
import { transactionHashUtils } from '@0x/order-utils';
import { blockchainTests, constants, expect, randomAddress, transactionHashUtils } from '@0x/contracts-test-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 => {
let coordinatorContract: CoordinatorContract;
@@ -41,8 +44,12 @@ blockchainTests.resets('Libs tests', env => {
transactionHash: transactionHashUtils.getTransactionHashHex(signedTx),
transactionSignature: signedTx.signature,
};
const expectedApprovalHash = hashUtils.getApprovalHashHex(signedTx, coordinatorContract.address, txOrigin);
const approvalHash = await coordinatorContract.getCoordinatorApprovalHash.callAsync(approval);
const expectedApprovalHash = await hashUtils.getApprovalHashHexAsync(
signedTx,
coordinatorContract.address,
txOrigin,
);
const approvalHash = await coordinatorContract.getCoordinatorApprovalHash(approval).callAsync();
expect(expectedApprovalHash).to.eq(approvalHash);
});
});

View File

@@ -1,18 +1,24 @@
import { constants as exchangeConstants, exchangeDataEncoder, ExchangeFunctionName } from '@0x/contracts-exchange';
import { exchangeDataEncoder } from '@0x/contracts-exchange';
import {
blockchainTests,
constants,
ExchangeFunctionName,
expect,
hexConcat,
hexSlice,
randomAddress,
TransactionFactory,
transactionHashUtils,
} 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 { BigNumber, LibBytesRevertErrors } from '@0x/utils';
import { BigNumber, CoordinatorRevertErrors } 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 => {
let chainId: number;
@@ -70,14 +76,14 @@ blockchainTests.resets('Mixins tests', env => {
const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EthSign);
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);
});
it('should return the correct address using the EIP712 signature type', async () => {
const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EIP712);
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);
});
it('should revert with with the Illegal signature type', async () => {
@@ -88,7 +94,7 @@ blockchainTests.resets('Mixins tests', env => {
SignatureType.Illegal,
);
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(
CoordinatorRevertErrors.SignatureErrorCodes.Illegal,
transactionHash,
@@ -101,7 +107,7 @@ blockchainTests.resets('Mixins tests', env => {
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat(SignatureType.Invalid);
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(
CoordinatorRevertErrors.SignatureErrorCodes.Invalid,
transactionHash,
@@ -117,7 +123,7 @@ blockchainTests.resets('Mixins tests', env => {
SignatureType.NSignatureTypes,
);
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(
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
transactionHash,
@@ -133,7 +139,7 @@ blockchainTests.resets('Mixins tests', env => {
SignatureType.Wallet,
);
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(
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
transactionHash,
@@ -144,11 +150,11 @@ blockchainTests.resets('Mixins tests', env => {
});
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 () => {
const orders = [defaultOrder];
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 => ({
...order,
signature: constants.NULL_BYTES,
@@ -158,11 +164,11 @@ blockchainTests.resets('Mixins tests', env => {
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 () => {
const orders = [defaultOrder, defaultOrder];
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 => ({
...order,
signature: constants.NULL_BYTES,
@@ -172,11 +178,11 @@ blockchainTests.resets('Mixins tests', env => {
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 () => {
const orders = [defaultOrder, defaultOrder];
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 => ({
...order,
signature: constants.NULL_BYTES,
@@ -186,11 +192,11 @@ blockchainTests.resets('Mixins tests', env => {
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 () => {
const orders = [defaultOrder, defaultOrder];
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 => ({
...order,
signature: constants.NULL_BYTES,
@@ -200,18 +206,18 @@ blockchainTests.resets('Mixins tests', env => {
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 () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
const emptyArray: any[] = [];
expect(emptyArray).to.deep.eq(decodedOrders);
});
}
it('should decode an empty array for invalid data', async () => {
const data = '0x0123456789';
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
const emptyArray: any[] = [];
expect(emptyArray).to.deep.eq(decodedOrders);
});
@@ -222,24 +228,22 @@ blockchainTests.resets('Mixins tests', env => {
new BigNumber(3), // the length of data
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', () => {
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 () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval.signature],
{ from: transactionSignerAddress },
);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval.signature,
])
.callAsync({ from: transactionSignerAddress });
});
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1]`, async () => {
const order = {
@@ -249,73 +253,59 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [order];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval.signature],
{ from: transactionSignerAddress },
);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval.signature,
])
.callAsync({ from: transactionSignerAddress });
});
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[],
{
await mixins
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
.callAsync({
from: approvalSignerAddress1,
},
);
});
});
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[approval.signature],
{ from: approvalSignerAddress1 },
);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [
approval.signature,
])
.callAsync({ from: approvalSignerAddress1 });
});
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[],
{
await mixins
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
.callAsync({
from: approvalSignerAddress1,
},
);
});
});
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const signature = hexConcat(
hexSlice(approval.signature, 0, 2),
'0xFFFFFFFF',
hexSlice(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);
expect(tx).to.revertWith(
@@ -326,37 +316,33 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval.signature],
{ from: approvalSignerAddress2 },
);
const tx = mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval.signature,
])
.callAsync({ from: approvalSignerAddress2 });
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
});
}
});
describe('Batch order approvals', () => {
for (const fnName of [
...exchangeConstants.BATCH_FILL_FN_NAMES,
...exchangeConstants.MARKET_FILL_FN_NAMES,
...exchangeConstants.MATCH_ORDER_FN_NAMES,
...constants.BATCH_FILL_FN_NAMES,
...constants.MARKET_FILL_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 () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval.signature],
{ from: transactionSignerAddress },
);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval.signature,
])
.callAsync({ from: transactionSignerAddress });
});
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 => ({
@@ -365,14 +351,12 @@ blockchainTests.resets('Mixins tests', env => {
}));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval.signature],
{ from: transactionSignerAddress },
);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval.signature,
])
.callAsync({ from: transactionSignerAddress });
});
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
const orders = [defaultOrder, defaultOrder].map(order => ({
@@ -381,79 +365,62 @@ blockchainTests.resets('Mixins tests', env => {
}));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
{ from: transactionSignerAddress },
);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
.callAsync({ from: transactionSignerAddress });
});
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 data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval.signature],
{ from: transactionSignerAddress },
);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval.signature,
])
.callAsync({ from: transactionSignerAddress });
});
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 data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
);
const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval1.signature,
approval2.signature,
])
.callAsync({ from: transactionSignerAddress });
});
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[],
{ from: approvalSignerAddress1 },
);
await mixins
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
.callAsync({ from: approvalSignerAddress1 });
});
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval2.signature],
{ from: approvalSignerAddress1 },
);
const tx = mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval2.signature,
])
.callAsync({ from: approvalSignerAddress1 });
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 () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
{ from: transactionSignerAddress },
);
const tx = mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
.callAsync({ from: transactionSignerAddress });
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith(
@@ -464,19 +431,17 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const signature = hexConcat(
hexSlice(approval.signature, 0, 2),
'0xFFFFFFFF',
hexSlice(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);
expect(tx).to.revertWith(
@@ -487,20 +452,19 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
const approvalSignature2 = hexConcat(
hexSlice(approval2.signature, 0, 2),
'0xFFFFFFFF',
hexSlice(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);
expect(tx).to.revertWith(
@@ -511,19 +475,17 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
const approvalSignature2 = hexConcat(
hexSlice(approval2.signature, 0, 2),
'0xFFFFFFFF',
hexSlice(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);
expect(tx).to.revertWith(
@@ -534,15 +496,13 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval1.signature],
{ from: approvalSignerAddress2 },
);
const tx = mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval1.signature,
])
.callAsync({ from: approvalSignerAddress2 });
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
});
}
@@ -552,36 +512,24 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
{ from: transactionSignerAddress },
);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
.callAsync({ from: transactionSignerAddress });
});
it('should allow the tx signer to call `batchCancelOrders` without approval', async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.BatchCancelOrders, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
{ from: transactionSignerAddress },
);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
.callAsync({ from: transactionSignerAddress });
});
it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
{ from: transactionSignerAddress },
);
await mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
.callAsync({ from: transactionSignerAddress });
});
});
});

View File

@@ -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;
},
};

View File

@@ -1,3 +0,0 @@
export { hashUtils } from './hash_utils';
export { ApprovalFactory } from './approval_factory';
export * from './types';

View 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';

View File

@@ -5,18 +5,24 @@
"files": [
"generated-artifacts/Coordinator.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/LibCoordinatorApproval.json",
"generated-artifacts/LibCoordinatorRichErrors.json",
"generated-artifacts/LibEIP712CoordinatorDomain.json",
"generated-artifacts/MixinCoordinatorApprovalVerifier.json",
"generated-artifacts/MixinCoordinatorCore.json",
"generated-artifacts/MixinCoordinatorRegistryCore.json",
"generated-artifacts/MixinSignatureValidator.json"
"test/generated-artifacts/Coordinator.json",
"test/generated-artifacts/CoordinatorRegistry.json",
"test/generated-artifacts/ICoordinatorApprovalVerifier.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"]
}

View File

@@ -3,5 +3,5 @@
"compilerOptions": {
"outDir": "lib"
},
"include": ["./src/**/*"]
"include": ["./src/**/*", "./test/**/*"]
}

View 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

View File

@@ -1,4 +1,82 @@
[
{
"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",
"changes": [

View File

@@ -5,6 +5,32 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## 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_
* Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData (#2034)

View File

@@ -1,5 +1,5 @@
{
"artifactsDir": "./generated-artifacts",
"artifactsDir": "./test/generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": false,
"isOfflineMode": false,
@@ -7,7 +7,7 @@
"evmVersion": "constantinople",
"optimizer": {
"enabled": true,
"runs": 10000,
"runs": 1666,
"details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
},
"outputSelection": {

View File

@@ -19,6 +19,11 @@
pragma solidity ^0.5.5;
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 "./OrderTransferSimulationUtils.sol";
import "./LibTransactionDecoder.sol";
@@ -29,6 +34,7 @@ import "./EthBalanceChecker.sol";
contract DevUtils is
OrderValidationUtils,
LibTransactionDecoder,
LibEIP712ExchangeDomain,
EthBalanceChecker,
OrderTransferSimulationUtils
{
@@ -36,5 +42,32 @@ contract DevUtils is
public
OrderValidationUtils(_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)
);
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-dev-utils",
"version": "0.1.0-beta.1",
"version": "1.0.0",
"engines": {
"node": ">=6.12"
},
@@ -8,22 +8,27 @@
"main": "lib/src/index.js",
"scripts": {
"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",
"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",
"watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"contracts:gen": "contracts-gen",
"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 test/generated-wrappers --backend ethers",
"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 ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"contracts:gen": "contracts-gen generate",
"contracts:copy": "contracts-gen copy",
"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",
"compile:truffle": "truffle compile"
"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",
"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": {
"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."
},
"repository": {
@@ -36,28 +41,25 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md",
"devDependencies": {
"@0x/abi-gen": "^4.4.0-beta.1",
"@0x/contracts-gen": "^1.1.0-beta.1",
"@0x/sol-compiler": "^3.2.0-beta.1",
"@0x/tslint-config": "^3.1.0-beta.1",
"@0x/abi-gen": "^5.0.0",
"@0x/assert": "^3.0.0",
"@0x/contracts-gen": "^2.0.0",
"@0x/sol-compiler": "^4.0.0",
"@0x/ts-doc-gen": "^0.0.22",
"@0x/tslint-config": "^4.0.0",
"@types/node": "*",
"ethereum-types": "^3.0.0",
"ethers": "~4.0.4",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typedoc": "^0.15.0",
"typescript": "3.0.1"
},
"dependencies": {
"@0x/assert": "^2.2.0-beta.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"
"@0x/base-contract": "^6.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -6,16 +6,10 @@
import { ContractArtifact } from 'ethereum-types';
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 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 = {
DevUtils: DevUtils as ContractArtifact,
EthBalanceChecker: EthBalanceChecker as ContractArtifact,
LibAssetData: LibAssetData as ContractArtifact,
LibTransactionDecoder: LibTransactionDecoder as ContractArtifact,
OrderTransferSimulationUtils: OrderTransferSimulationUtils as ContractArtifact,
OrderValidationUtils: OrderValidationUtils as ContractArtifact,
};

View File

@@ -1,2 +1,30 @@
export * from './artifacts';
export * from './wrappers';
export { artifacts } from './artifacts';
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';

View File

@@ -4,8 +4,5 @@
* -----------------------------------------------------------------------------
*/
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_transaction_decoder';
export * from '../generated-wrappers/order_transfer_simulation_utils';
export * from '../generated-wrappers/order_validation_utils';

View 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,
};

View 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';

View File

@@ -4,11 +4,14 @@
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": [
"generated-artifacts/DevUtils.json",
"generated-artifacts/EthBalanceChecker.json",
"generated-artifacts/LibAssetData.json",
"generated-artifacts/LibTransactionDecoder.json",
"generated-artifacts/OrderTransferSimulationUtils.json",
"generated-artifacts/OrderValidationUtils.json"
"test/generated-artifacts/DevUtils.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"]
}

View File

@@ -0,0 +1,7 @@
{
"extends": "../../typedoc-tsconfig",
"compilerOptions": {
"outDir": "lib"
},
"include": ["./src/**/*", "./test/**/*"]
}

View 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

View File

@@ -1,4 +1,50 @@
[
{
"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",
"changes": [

View File

@@ -5,6 +5,24 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## 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_
* Dependencies updated

View File

@@ -1,5 +1,5 @@
{
"artifactsDir": "./generated-artifacts",
"artifactsDir": "./test/generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": false,
"isOfflineMode": false,

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc1155",
"version": "1.2.0-beta.1",
"version": "2.0.0",
"engines": {
"node": ">=6.12"
},
@@ -12,7 +12,7 @@
"scripts": {
"build": "yarn pre_build && tsc -b",
"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",
"rebuild_and_test": "run-s build test",
"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",
"compile": "sol-compiler",
"watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"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 test/generated-wrappers --backend ethers",
"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 ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage: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",
"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",
"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": {
"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."
},
"repository": {
@@ -48,11 +52,15 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
"devDependencies": {
"@0x/abi-gen": "^4.4.0-beta.1",
"@0x/contracts-gen": "^1.1.0-beta.1",
"@0x/dev-utils": "^2.4.0-beta.1",
"@0x/sol-compiler": "^3.2.0-beta.1",
"@0x/tslint-config": "^3.1.0-beta.1",
"@0x/abi-gen": "^5.0.0",
"@0x/contracts-gen": "^2.0.0",
"@0x/contracts-utils": "^4.0.0",
"@0x/dev-utils": "^3.0.0",
"@0x/sol-compiler": "^4.0.0",
"@0x/ts-doc-gen": "^0.0.22",
"@0x/tslint-config": "^4.0.0",
"@0x/types": "^3.0.0",
"@0x/typescript-typings": "^5.0.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "*",
@@ -60,6 +68,7 @@
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.0.0",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
"npm-run-all": "^4.1.2",
@@ -67,17 +76,14 @@
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typedoc": "^0.15.0",
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.5.0-beta.1",
"@0x/contracts-test-utils": "^3.2.0-beta.1",
"@0x/contracts-utils": "^3.3.0-beta.1",
"@0x/types": "^2.5.0-beta.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",
"@0x/base-contract": "^6.0.0",
"@0x/contracts-test-utils": "^4.0.0",
"@0x/utils": "^5.0.0",
"@0x/web3-wrapper": "^7.0.0",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -8,16 +8,10 @@ import { ContractArtifact } from 'ethereum-types';
import * as DummyERC1155Receiver from '../generated-artifacts/DummyERC1155Receiver.json';
import * as ERC1155 from '../generated-artifacts/ERC1155.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 MixinNonFungibleToken from '../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,
};

View File

@@ -1,31 +1,22 @@
import { LogDecoder } from '@0x/contracts-test-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 * as _ from 'lodash';
import { artifacts, ERC1155MintableContract, ERC1155TransferSingleEventArgs } from '../../src';
const expect = chai.expect;
import { ERC1155MintableContract, ERC1155TransferSingleEventArgs } from './wrappers';
export class Erc1155Wrapper {
private readonly _erc1155Contract: ERC1155MintableContract;
private readonly _web3Wrapper: Web3Wrapper;
private readonly _contractOwner: string;
private readonly _logDecoder: LogDecoder;
constructor(contractInstance: ERC1155MintableContract, provider: Provider, contractOwner: string) {
this._erc1155Contract = contractInstance;
this._web3Wrapper = new Web3Wrapper(provider);
this._contractOwner = contractOwner;
this._logDecoder = new LogDecoder(this._web3Wrapper, artifacts);
}
public getContract(): ERC1155MintableContract {
return this._erc1155Contract;
}
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;
}
public async safeTransferFromAsync(
@@ -38,11 +29,11 @@ export class Erc1155Wrapper {
): Promise<TransactionReceiptWithDecodedLogs> {
const spender = delegatedSpender === undefined ? from : delegatedSpender;
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
await this._erc1155Contract.safeTransferFrom.sendTransactionAsync(from, to, token, value, callbackDataHex, {
const tx = await this._erc1155Contract
.safeTransferFrom(from, to, token, value, callbackDataHex)
.awaitTransactionSuccessAsync({
from: spender,
}),
);
});
return tx;
}
public async safeBatchTransferFromAsync(
@@ -55,16 +46,9 @@ export class Erc1155Wrapper {
): Promise<TransactionReceiptWithDecodedLogs> {
const spender = delegatedSpender === undefined ? from : delegatedSpender;
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
await this._erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
from,
to,
tokens,
values,
callbackDataHex,
{ from: spender },
),
);
const tx = await this._erc1155Contract
.safeBatchTransferFrom(from, to, tokens, values, callbackDataHex)
.awaitTransactionSuccessAsync({ from: spender });
return tx;
}
public async mintFungibleTokensAsync(
@@ -73,11 +57,9 @@ export class Erc1155Wrapper {
): Promise<BigNumber> {
const tokenUri = 'dummyFungibleToken';
const tokenIsNonFungible = false;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
await this._erc1155Contract.create.sendTransactionAsync(tokenUri, tokenIsNonFungible, {
from: this._contractOwner,
}),
);
const tx = await this._erc1155Contract.create(tokenUri, tokenIsNonFungible).awaitTransactionSuccessAsync({
from: this._contractOwner,
});
// tslint:disable-next-line no-unnecessary-type-assertion
const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>;
const tokenId = createFungibleTokenLog.args.id;
@@ -95,25 +77,20 @@ export class Erc1155Wrapper {
tokenAmountsAsArray.push(tokenAmounts);
});
}
await this._erc1155Contract.mintFungible.awaitTransactionSuccessAsync(
tokenId,
beneficiaries,
tokenAmountsAsArray,
{ from: this._contractOwner },
);
await this._erc1155Contract
.mintFungible(tokenId, beneficiaries, tokenAmountsAsArray)
.awaitTransactionSuccessAsync({ from: this._contractOwner });
}
public async mintNonFungibleTokensAsync(beneficiaries: string[]): Promise<[BigNumber, BigNumber[]]> {
const tokenUri = 'dummyNonFungibleToken';
const tokenIsNonFungible = true;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
await this._erc1155Contract.create.sendTransactionAsync(tokenUri, tokenIsNonFungible, {
from: this._contractOwner,
}),
);
const tx = await this._erc1155Contract.create(tokenUri, tokenIsNonFungible).awaitTransactionSuccessAsync({
from: this._contractOwner,
});
// tslint:disable-next-line no-unnecessary-type-assertion
const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>;
const token = createFungibleTokenLog.args.id;
await this._erc1155Contract.mintNonFungible.awaitTransactionSuccessAsync(token, beneficiaries, {
await this._erc1155Contract.mintNonFungible(token, beneficiaries).awaitTransactionSuccessAsync({
from: this._contractOwner,
});
const encodedNftIds: BigNumber[] = [];
@@ -131,15 +108,13 @@ export class Erc1155Wrapper {
beneficiary: string,
isApproved: boolean,
): Promise<TransactionReceiptWithDecodedLogs> {
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
await this._erc1155Contract.setApprovalForAll.sendTransactionAsync(beneficiary, isApproved, {
from: owner,
}),
);
const tx = await this._erc1155Contract.setApprovalForAll(beneficiary, isApproved).awaitTransactionSuccessAsync({
from: owner,
});
return tx;
}
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;
}
public async assertBalancesAsync(
@@ -157,22 +132,24 @@ export class Erc1155Wrapper {
});
const balances = await this.getBalancesAsync(ownersExtended, tokensExtended);
_.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> {
return this._erc1155Contract.isNonFungibleItem.callAsync(tokenId);
return this._erc1155Contract.isNonFungibleItem(tokenId).callAsync();
}
public async isFungibleItemAsync(tokenId: BigNumber): Promise<boolean> {
return !(await this.isNonFungibleItemAsync(tokenId));
}
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.
*/
public async getBalanceAsync(ownerAddress: string, tokenId: BigNumber): Promise<BigNumber> {
return this._erc1155Contract.balanceOf.callAsync(ownerAddress, tokenId);
return this._erc1155Contract.balanceOf(ownerAddress, tokenId).callAsync();
}
}

View File

@@ -1,3 +1,45 @@
export * from './wrappers';
export * from './artifacts';
export { Erc1155Wrapper } from '../test/utils/erc1155_wrapper';
export {
DummyERC1155ReceiverContract,
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';

View File

@@ -6,7 +6,4 @@
export * from '../generated-wrappers/dummy_erc1155_receiver';
export * from '../generated-wrappers/erc1155';
export * from '../generated-wrappers/erc1155_mintable';
export * from '../generated-wrappers/i_erc1155_mintable';
export * from '../generated-wrappers/i_erc1155_receiver';
export * from '../generated-wrappers/ierc1155';
export * from '../generated-wrappers/mixin_non_fungible_token';

View 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,
};

View File

@@ -6,21 +6,19 @@ import {
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { SafeMathRevertErrors } from '@0x/contracts-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { RevertReason } from '@0x/types';
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types';
import * as _ from 'lodash';
import {
artifacts,
DummyERC1155ReceiverBatchTokenReceivedEventArgs,
DummyERC1155ReceiverContract,
ERC1155MintableContract,
} from '../src';
import { Erc1155Wrapper } from '../src/erc1155_wrapper';
import { ERC1155MintableContract } from '../src/wrappers';
import { Erc1155Wrapper } from './utils/erc1155_wrapper';
import { artifacts } from './artifacts';
import { DummyERC1155ReceiverBatchTokenReceivedEventArgs, DummyERC1155ReceiverContract } from './wrappers';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
@@ -179,14 +177,9 @@ describe('ERC1155Token', () => {
valueToTransfer,
);
// execute transfer
const tx = erc1155Contract.safeTransferFrom.sendTransactionAsync(
spender,
receiver,
tokenToTransfer,
valueToTransfer,
receiverCallbackData,
{ from: spender },
);
const tx = erc1155Contract
.safeTransferFrom(spender, receiver, tokenToTransfer, valueToTransfer, receiverCallbackData)
.sendTransactionAsync({ from: spender });
return expect(tx).to.revertWith(expectedError);
});
it('should revert if callback reverts', async () => {
@@ -196,19 +189,14 @@ describe('ERC1155Token', () => {
// set receiver to reject balances
const shouldRejectTransfer = true;
await web3Wrapper.awaitTransactionSuccessAsync(
await erc1155Receiver.setRejectTransferFlag.sendTransactionAsync(shouldRejectTransfer),
await erc1155Receiver.setRejectTransferFlag(shouldRejectTransfer).sendTransactionAsync(),
constants.AWAIT_TRANSACTION_MINED_MS,
);
// execute transfer
await expectTransactionFailedAsync(
erc1155Contract.safeTransferFrom.sendTransactionAsync(
spender,
receiver,
tokenToTransfer,
valueToTransfer,
receiverCallbackData,
{ from: spender },
),
erc1155Contract
.safeTransferFrom(spender, receiver, tokenToTransfer, valueToTransfer, receiverCallbackData)
.sendTransactionAsync({ from: spender }),
RevertReason.TransferRejected,
);
});
@@ -355,14 +343,9 @@ describe('ERC1155Token', () => {
valuesToTransfer[0],
);
// execute transfer
const tx = erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
spender,
receiver,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
{ from: spender },
);
const tx = erc1155Contract
.safeBatchTransferFrom(spender, receiver, tokensToTransfer, valuesToTransfer, receiverCallbackData)
.sendTransactionAsync({ from: spender });
return expect(tx).to.revertWith(expectedError);
});
it('should revert if callback reverts', async () => {
@@ -372,19 +355,14 @@ describe('ERC1155Token', () => {
// set receiver to reject balances
const shouldRejectTransfer = true;
await web3Wrapper.awaitTransactionSuccessAsync(
await erc1155Receiver.setRejectTransferFlag.sendTransactionAsync(shouldRejectTransfer),
await erc1155Receiver.setRejectTransferFlag(shouldRejectTransfer).sendTransactionAsync(),
constants.AWAIT_TRANSACTION_MINED_MS,
);
// execute transfer
await expectTransactionFailedAsync(
erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
spender,
receiver,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
{ from: spender },
),
erc1155Contract
.safeBatchTransferFrom(spender, receiver, tokensToTransfer, valuesToTransfer, receiverCallbackData)
.sendTransactionAsync({ from: spender }),
RevertReason.TransferRejected,
);
});
@@ -432,14 +410,9 @@ describe('ERC1155Token', () => {
await erc1155Wrapper.assertBalancesAsync(tokenHolders, [tokenToTransfer], expectedInitialBalances);
// execute transfer
await expectTransactionFailedAsync(
erc1155Contract.safeTransferFrom.sendTransactionAsync(
spender,
receiver,
tokenToTransfer,
valueToTransfer,
receiverCallbackData,
{ from: delegatedSpender },
),
erc1155Contract
.safeTransferFrom(spender, receiver, tokenToTransfer, valueToTransfer, receiverCallbackData)
.sendTransactionAsync({ from: delegatedSpender }),
RevertReason.InsufficientAllowance,
);
});
@@ -485,14 +458,9 @@ describe('ERC1155Token', () => {
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
// execute transfer
await expectTransactionFailedAsync(
erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
spender,
receiver,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
{ from: delegatedSpender },
),
erc1155Contract
.safeBatchTransferFrom(spender, receiver, tokensToTransfer, valuesToTransfer, receiverCallbackData)
.sendTransactionAsync({ from: delegatedSpender }),
RevertReason.InsufficientAllowance,
);
});

View 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';

View File

@@ -6,10 +6,14 @@
"generated-artifacts/DummyERC1155Receiver.json",
"generated-artifacts/ERC1155.json",
"generated-artifacts/ERC1155Mintable.json",
"generated-artifacts/IERC1155.json",
"generated-artifacts/IERC1155Mintable.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"]
}

View File

@@ -0,0 +1,7 @@
{
"extends": "../../typedoc-tsconfig",
"compilerOptions": {
"outDir": "lib"
},
"include": ["./src/**/*", "./test/**/*"]
}

View 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

View File

@@ -0,0 +1,30 @@
[
{
"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
}
]
}
]

View File

@@ -0,0 +1,18 @@
<!--
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.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)

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1,67 @@
## ERC20BridgeSampler
This package contains contracts used in DEX aggregation.
This is an MVP implementation, which agnostically samples DEXes for off-chain sorting and order generation. It is entirely read-only and never not touches any funds.
## Installation
**Install**
```bash
npm install @0x/contracts-erc20-bridge-sampler --save
```
## Contributing
We strongly recommend that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository.
For proposals regarding the 0x protocol's smart contract architecture, message format, or additional functionality, go to the [0x Improvement Proposals (ZEIPs)](https://github.com/0xProject/ZEIPs) repository and follow the contribution guidelines provided therein.
Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
### Install Dependencies
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
```bash
yarn config set workspaces-experimental true
```
Then install dependencies
```bash
yarn install
```
### Build
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
PKG=@0x/contracts-erc20-bridge-sampler yarn build
```
Or continuously rebuild on change:
```bash
PKG=@0x/contracts-erc20-bridge-sampler yarn watch
```
### Clean
```bash
yarn clean
```
### Lint
```bash
yarn lint
```
### Run Tests
```bash
yarn test
```

View File

@@ -0,0 +1,26 @@
{
"artifactsDir": "./test/generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": false,
"isOfflineMode": false,
"compilerSettings": {
"evmVersion": "constantinople",
"optimizer": {
"enabled": true,
"runs": 1000000,
"details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
},
"outputSelection": {
"*": {
"*": [
"abi",
"devdoc",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
"evm.deployedBytecode.sourceMap"
]
}
}
}
}

View File

@@ -0,0 +1,92 @@
/*
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-asset-proxy/contracts/src/interfaces/IUniswapExchangeFactory.sol";
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
import "./IEth2Dai.sol";
import "./IKyberNetwork.sol";
contract DeploymentConstants {
/// @dev Address of the 0x Exchange contract.
address constant public EXCHANGE_ADDRESS = 0x080bf510FCbF18b91105470639e9561022937712;
/// @dev Address of the Eth2Dai MatchingMarket contract.
address constant public ETH2DAI_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
/// @dev Address of the UniswapExchangeFactory contract.
address constant public UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
/// @dev Address of the KyberNeworkProxy contract.
address constant public KYBER_NETWORK_PROXY_ADDRESS = 0x818E6FECD516Ecc3849DAf6845e3EC868087B755;
/// @dev Address of the WETH contract.
address constant public WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
/// @dev Kyber ETH pseudo-address.
address constant public KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/// @dev An overridable way to retrieve the 0x Exchange contract.
/// @return zeroex The 0x Exchange contract.
function _getExchangeContract()
internal
view
returns (IExchange zeroex)
{
return IExchange(EXCHANGE_ADDRESS);
}
/// @dev An overridable way to retrieve the Eth2Dai exchange contract.
/// @return eth2dai The Eth2Dai exchange contract.
function _getEth2DaiContract()
internal
view
returns (IEth2Dai eth2dai)
{
return IEth2Dai(ETH2DAI_ADDRESS);
}
/// @dev An overridable way to retrieve the Uniswap exchange factory contract.
/// @return uniswap The UniswapExchangeFactory contract.
function _getUniswapExchangeFactoryContract()
internal
view
returns (IUniswapExchangeFactory uniswap)
{
return IUniswapExchangeFactory(UNISWAP_EXCHANGE_FACTORY_ADDRESS);
}
/// @dev An overridable way to retrieve the Kyber network proxy contract.
/// @return kyber The KyberNeworkProxy contract.
function _getKyberNetworkContract()
internal
view
returns (IKyberNetwork kyber)
{
return IKyberNetwork(KYBER_NETWORK_PROXY_ADDRESS);
}
/// @dev An overridable way to retrieve the WETH contract address.
/// @return weth The WETH contract address.
function _getWETHAddress()
internal
view
returns (address weth)
{
return WETH_ADDRESS;
}
}

View File

@@ -0,0 +1,451 @@
/*
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-asset-proxy/contracts/src/interfaces/IUniswapExchangeFactory.sol";
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "./IERC20BridgeSampler.sol";
import "./IEth2Dai.sol";
import "./IKyberNetwork.sol";
import "./IUniswapExchangeQuotes.sol";
import "./DeploymentConstants.sol";
contract ERC20BridgeSampler is
IERC20BridgeSampler,
DeploymentConstants
{
bytes4 constant internal ERC20_PROXY_ID = 0xf47261b0; // bytes4(keccak256("ERC20Token(address)"));
/// @dev Query native orders and sample sell quotes on multiple DEXes at once.
/// @param orders Native orders to query.
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return orderInfos `OrderInfo`s for each order in `orders`.
/// @return makerTokenAmountsBySource Maker amounts bought for each source at
/// each taker token amount. First indexed by source index, then sample
/// index.
function queryOrdersAndSampleSells(
LibOrder.Order[] memory orders,
address[] memory sources,
uint256[] memory takerTokenAmounts
)
public
view
returns (
LibOrder.OrderInfo[] memory orderInfos,
uint256[][] memory makerTokenAmountsBySource
)
{
require(orders.length != 0, "EMPTY_ORDERS");
orderInfos = queryOrders(orders);
makerTokenAmountsBySource = sampleSells(
sources,
_assetDataToTokenAddress(orders[0].takerAssetData),
_assetDataToTokenAddress(orders[0].makerAssetData),
takerTokenAmounts
);
}
/// @dev Query native orders and sample buy quotes on multiple DEXes at once.
/// @param orders Native orders to query.
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return orderInfos `OrderInfo`s for each order in `orders`.
/// @return takerTokenAmountsBySource Taker amounts sold for each source at
/// each maker token amount. First indexed by source index, then sample
/// index.
function queryOrdersAndSampleBuys(
LibOrder.Order[] memory orders,
address[] memory sources,
uint256[] memory makerTokenAmounts
)
public
view
returns (
LibOrder.OrderInfo[] memory orderInfos,
uint256[][] memory makerTokenAmountsBySource
)
{
require(orders.length != 0, "EMPTY_ORDERS");
orderInfos = queryOrders(orders);
makerTokenAmountsBySource = sampleBuys(
sources,
_assetDataToTokenAddress(orders[0].takerAssetData),
_assetDataToTokenAddress(orders[0].makerAssetData),
makerTokenAmounts
);
}
/// @dev Queries the status of several native orders.
/// @param orders Native orders to query.
/// @return orderInfos Order info for each respective order.
function queryOrders(LibOrder.Order[] memory orders)
public
view
returns (LibOrder.OrderInfo[] memory orderInfos)
{
uint256 numOrders = orders.length;
orderInfos = new LibOrder.OrderInfo[](numOrders);
for (uint256 i = 0; i < numOrders; i++) {
orderInfos[i] = _getExchangeContract().getOrderInfo(orders[i]);
}
}
/// @dev Sample sell quotes on multiple DEXes at once.
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmountsBySource Maker amounts bought for each source at
/// each taker token amount. First indexed by source index, then sample
/// index.
function sampleSells(
address[] memory sources,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
view
returns (uint256[][] memory makerTokenAmountsBySource)
{
uint256 numSources = sources.length;
makerTokenAmountsBySource = new uint256[][](numSources);
for (uint256 i = 0; i < numSources; i++) {
makerTokenAmountsBySource[i] = _sampleSellSource(
sources[i],
takerToken,
makerToken,
takerTokenAmounts
);
}
}
/// @dev Query native orders and sample buy quotes on multiple DEXes at once.
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmountsBySource Taker amounts sold for each source at
/// each maker token amount. First indexed by source index, then sample
/// index.
function sampleBuys(
address[] memory sources,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
view
returns (uint256[][] memory takerTokenAmountsBySource)
{
uint256 numSources = sources.length;
takerTokenAmountsBySource = new uint256[][](numSources);
for (uint256 i = 0; i < numSources; i++) {
takerTokenAmountsBySource[i] = _sampleBuySource(
sources[i],
takerToken,
makerToken,
makerTokenAmounts
);
}
}
/// @dev Sample sell quotes from Kyber.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromKyberNetwork(
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
address _takerToken = takerToken == _getWETHAddress() ? KYBER_ETH_ADDRESS : takerToken;
address _makerToken = makerToken == _getWETHAddress() ? KYBER_ETH_ADDRESS : makerToken;
uint256 takerTokenDecimals = _getTokenDecimals(takerToken);
uint256 makerTokenDecimals = _getTokenDecimals(makerToken);
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
(uint256 rate,) = _getKyberNetworkContract().getExpectedRate(
_takerToken,
_makerToken,
takerTokenAmounts[i]
);
makerTokenAmounts[i] =
rate *
takerTokenAmounts[i] *
10 ** makerTokenDecimals /
10 ** takerTokenDecimals /
10 ** 18;
}
}
/// @dev Sample sell quotes from Eth2Dai/Oasis.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromEth2Dai(
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
makerTokenAmounts[i] = _getEth2DaiContract().getBuyAmount(
makerToken,
takerToken,
takerTokenAmounts[i]
);
}
}
/// @dev Sample buy quotes from Eth2Dai/Oasis.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Maker token sell amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromEth2Dai(
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
takerTokenAmounts[i] = _getEth2DaiContract().getPayAmount(
takerToken,
makerToken,
makerTokenAmounts[i]
);
}
}
/// @dev Sample sell quotes from Uniswap.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromUniswap(
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
IUniswapExchangeQuotes takerTokenExchange = takerToken == _getWETHAddress() ?
IUniswapExchangeQuotes(0) : _getUniswapExchange(takerToken);
IUniswapExchangeQuotes makerTokenExchange = makerToken == _getWETHAddress() ?
IUniswapExchangeQuotes(0) : _getUniswapExchange(makerToken);
for (uint256 i = 0; i < numSamples; i++) {
if (makerToken == _getWETHAddress()) {
makerTokenAmounts[i] = takerTokenExchange.getTokenToEthInputPrice(
takerTokenAmounts[i]
);
} else if (takerToken == _getWETHAddress()) {
makerTokenAmounts[i] = makerTokenExchange.getEthToTokenInputPrice(
takerTokenAmounts[i]
);
} else {
uint256 ethBought = takerTokenExchange.getTokenToEthInputPrice(
takerTokenAmounts[i]
);
makerTokenAmounts[i] = makerTokenExchange.getEthToTokenInputPrice(
ethBought
);
}
}
}
/// @dev Sample buy quotes from Uniswap.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param makerTokenAmounts Maker token sell amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromUniswap(
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = new uint256[](numSamples);
IUniswapExchangeQuotes takerTokenExchange = takerToken == _getWETHAddress() ?
IUniswapExchangeQuotes(0) : _getUniswapExchange(takerToken);
IUniswapExchangeQuotes makerTokenExchange = makerToken == _getWETHAddress() ?
IUniswapExchangeQuotes(0) : _getUniswapExchange(makerToken);
for (uint256 i = 0; i < numSamples; i++) {
if (makerToken == _getWETHAddress()) {
takerTokenAmounts[i] = takerTokenExchange.getTokenToEthOutputPrice(
makerTokenAmounts[i]
);
} else if (takerToken == _getWETHAddress()) {
takerTokenAmounts[i] = makerTokenExchange.getEthToTokenOutputPrice(
makerTokenAmounts[i]
);
} else {
uint256 ethSold = makerTokenExchange.getEthToTokenOutputPrice(
makerTokenAmounts[i]
);
takerTokenAmounts[i] = takerTokenExchange.getTokenToEthOutputPrice(
ethSold
);
}
}
}
/// @dev Overridable way to get token decimals.
/// @param tokenAddress Address of the token.
/// @return decimals The decimal places for the token.
function _getTokenDecimals(address tokenAddress)
internal
view
returns (uint8 decimals)
{
return LibERC20Token.decimals(tokenAddress);
}
/// @dev Samples a supported sell source, defined by its address.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function _sampleSellSource(
address source,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
private
view
returns (uint256[] memory makerTokenAmounts)
{
if (source == address(_getEth2DaiContract())) {
return sampleSellsFromEth2Dai(takerToken, makerToken, takerTokenAmounts);
}
if (source == address(_getUniswapExchangeFactoryContract())) {
return sampleSellsFromUniswap(takerToken, makerToken, takerTokenAmounts);
}
if (source == address(_getKyberNetworkContract())) {
return sampleSellsFromKyberNetwork(takerToken, makerToken, takerTokenAmounts);
}
revert("UNSUPPORTED_SOURCE");
}
/// @dev Samples a supported buy source, defined by its address.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param makerTokenAmounts Maker token sell amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function _sampleBuySource(
address source,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
private
view
returns (uint256[] memory takerTokenAmounts)
{
if (source == address(_getEth2DaiContract())) {
return sampleBuysFromEth2Dai(takerToken, makerToken, makerTokenAmounts);
}
if (source == address(_getUniswapExchangeFactoryContract())) {
return sampleBuysFromUniswap(takerToken, makerToken, makerTokenAmounts);
}
revert("UNSUPPORTED_SOURCE");
}
/// @dev Retrive an existing Uniswap exchange contract.
/// Throws if the exchange does not exist.
/// @param tokenAddress Address of the token contract.
/// @return exchange `IUniswapExchangeQuotes` for the token.
function _getUniswapExchange(address tokenAddress)
private
view
returns (IUniswapExchangeQuotes exchange)
{
exchange = IUniswapExchangeQuotes(
address(_getUniswapExchangeFactoryContract().getExchange(tokenAddress))
);
require(address(exchange) != address(0), "UNSUPPORTED_UNISWAP_EXCHANGE");
}
/// @dev Extract the token address from ERC20 proxy asset data.
/// @param assetData ERC20 asset data.
/// @return tokenAddress The decoded token address.
function _assetDataToTokenAddress(bytes memory assetData)
private
pure
returns (address tokenAddress)
{
require(assetData.length == 36, "INVALID_ASSET_DATA");
bytes4 selector;
assembly {
selector := and(mload(add(assetData, 0x20)), 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
tokenAddress := mload(add(assetData, 0x24))
}
require(selector == ERC20_PROXY_ID, "UNSUPPORTED_ASSET_PROXY");
}
function _assertValidPair(address makerToken, address takerToken)
private
pure
{
require(makerToken != takerToken, "INVALID_TOKEN_PAIR");
}
}

View File

@@ -0,0 +1,111 @@
/*
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-exchange/contracts/src/interfaces/IExchange.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
interface IERC20BridgeSampler {
/// @dev Query native orders and sample sell orders on multiple DEXes at once.
/// @param orders Native orders to query.
/// @param sources Address of each DEX. Passing in an unknown DEX will throw.
/// @param takerTokenAmounts Taker sell amount for each sample.
/// @return orderInfos `OrderInfo`s for each order in `orders`.
/// @return makerTokenAmountsBySource Maker amounts bought for each source at
/// each taker token amount. First indexed by source index, then sample
/// index.
function queryOrdersAndSampleSells(
LibOrder.Order[] calldata orders,
address[] calldata sources,
uint256[] calldata takerTokenAmounts
)
external
view
returns (
LibOrder.OrderInfo[] memory orderInfos,
uint256[][] memory makerTokenAmountsBySource
);
/// @dev Query native orders and sample buy orders on multiple DEXes at once.
/// @param orders Native orders to query.
/// @param sources Address of each DEX. Passing in an unknown DEX will throw.
/// @param makerTokenAmounts Maker sell amount for each sample.
/// @return orderInfos `OrderInfo`s for each order in `orders`.
/// @return takerTokenAmountsBySource Taker amounts sold for each source at
/// each maker token amount. First indexed by source index, then sample
/// index.
function queryOrdersAndSampleBuys(
LibOrder.Order[] calldata orders,
address[] calldata sources,
uint256[] calldata makerTokenAmounts
)
external
view
returns (
LibOrder.OrderInfo[] memory orderInfos,
uint256[][] memory makerTokenAmountsBySource
);
/// @dev Queries the status of several native orders.
/// @param orders Native orders to query.
/// @return orderInfos Order info for each respective order.
function queryOrders(LibOrder.Order[] calldata orders)
external
view
returns (LibOrder.OrderInfo[] memory orderInfos);
/// @dev Sample sell quotes on multiple DEXes at once.
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmountsBySource Maker amounts bought for each source at
/// each taker token amount. First indexed by source index, then sample
/// index.
function sampleSells(
address[] calldata sources,
address takerToken,
address makerToken,
uint256[] calldata takerTokenAmounts
)
external
view
returns (uint256[][] memory makerTokenAmountsBySource);
/// @dev Query native orders and sample buy quotes on multiple DEXes at once.
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmountsBySource Taker amounts sold for each source at
/// each maker token amount. First indexed by source index, then sample
/// index.
function sampleBuys(
address[] calldata sources,
address takerToken,
address makerToken,
uint256[] calldata makerTokenAmounts
)
external
view
returns (uint256[][] memory takerTokenAmountsBySource);
}

Some files were not shown because too many files have changed in this diff Show More