Compare commits

..

334 Commits

Author SHA1 Message Date
xianny
6b0f3570b9 Publish
- @0x/contracts-asset-proxy@3.0.1
 - @0x/contracts-coordinator@3.0.1
 - @0x/contracts-dev-utils@1.0.1
 - @0x/contracts-erc1155@2.0.1
 - @0x/contracts-erc20-bridge-sampler@1.0.1
 - @0x/contracts-erc20@3.0.1
 - @0x/contracts-erc721@3.0.1
 - @0x/contracts-exchange-forwarder@4.0.1
 - @0x/contracts-exchange-libs@4.0.1
 - @0x/contracts-exchange@3.0.1
 - @0x/contracts-extensions@5.1.0
 - @0x/contracts-integrations@2.0.1
 - @0x/contracts-multisig@4.0.1
 - @0x/contracts-staking@2.0.1
 - @0x/contracts-test-utils@5.0.0
 - @0x/contracts-tests@0.0.7
 - @0x/contracts-utils@4.0.1
 - 0x.js@9.0.1
 - @0x/abi-gen@5.0.1
 - @0x/assert@3.0.1
 - @0x/asset-swapper@3.0.1
 - @0x/base-contract@6.0.1
 - @0x/connect@6.0.1
 - @0x/contract-artifacts@3.1.0
 - @0x/contract-wrappers-test@12.2.2
 - @0x/contract-wrappers@13.1.0
 - @0x/contracts-gen@2.0.1
 - @0x/dev-utils@3.0.1
 - @0x/instant@1.0.38
 - @0x/json-schemas@5.0.1
 - @0x/migrations@5.0.1
 - @0x/monorepo-scripts@1.0.44
 - @0x/order-utils@10.0.0
 - @0x/orderbook@1.0.1
 - @0x/sol-compiler@4.0.1
 - @0x/sol-coverage@4.0.1
 - @0x/sol-doc@3.0.1
 - @0x/sol-profiler@4.0.1
 - @0x/sol-resolver@3.0.1
 - @0x/sol-trace@3.0.1
 - @0x/sol-tracing-utils@7.0.1
 - @0x/sra-spec@3.0.1
 - @0x/subproviders@6.0.1
 - @0x/types@3.1.0
 - @0x/utils@5.1.0
 - @0x/web3-wrapper@7.0.1
2019-12-09 14:53:19 -08:00
xianny
71de0d04f3 Updated CHANGELOGS & MD docs 2019-12-09 14:53:05 -08:00
Xianny
99debff5d2 Add syntactic sugar for assetDataUtils (#2388)
* add syntactic sugar for assetDataUtils
2019-12-09 13:55:58 -08:00
Amir Bandeali
3bac6fcb27 Merge pull request #2377 from 0xProject/feat/forwarder/multi-affiliate-fees
Forwarder affiliate fee usability improvements
2019-12-08 19:13:28 -08:00
Amir Bandeali
4b842b81a0 Address PR feedback 2019-12-08 16:28:00 -08:00
Amir Bandeali
e2e4d048ab Update tests to use new Forwarder interface 2019-12-04 21:23:55 -08:00
Amir Bandeali
5574c368cd Allow different ETh fees to be specified for different feeRecipient addresses 2019-12-04 21:23:55 -08:00
Amir Bandeali
0d34f7b92e Add EthFeeLengthMismatchError 2019-12-04 21:23:55 -08:00
Amir Bandeali
5be0632e01 Add tests with multiple fee recipients 2019-12-04 21:23:55 -08:00
Amir Bandeali
79ea0bf9f4 Allow affiliate fee to be split between multiple fee recipient addresses 2019-12-04 21:23:54 -08:00
Amir Bandeali
b1929cb688 Update affiliate fee tests 2019-12-04 21:23:54 -08:00
Amir Bandeali
5ad98700e5 Remove FeePercentageTooLargeError rich revert 2019-12-04 21:22:54 -08:00
Amir Bandeali
a54624b697 Do not return ethFeePaid 2019-12-04 21:22:54 -08:00
Amir Bandeali
ca34c865af Remove max fee percentage for affiliate fees 2019-12-04 21:22:54 -08:00
Amir Bandeali
dde57b1eca Make affiliate fee a flat amount 2019-12-04 21:22:54 -08:00
Amir Bandeali
264b06938e Merge pull request #2378 from 0xProject/feat/bridges/chai-bridge
Implement ChaiBridge
2019-12-04 16:25:46 -08:00
John Johnson
99edb303e2 Merge pull request #2386 from 0xProject/feature/fix-unbound-provider
Fix unbound method in provider standardizer
2019-12-04 15:44:22 -08:00
John Johnson
104cc24dfc Fixing unbound provider (metamask v7.7 incorrectly binds this) 2019-12-04 15:09:00 -08:00
Xianny
fcbcbac889 Remove assetDataUtils everywhere (#2373)
* remove assetDataUtils everywhere

* export IAssetDataContract from @0x/contract-wrappers to allow @0x/instant to decode asset data  synchronously

* export generic function `decodeAssetDataOrThrow` and add ERC20Bridge support

* export `hexUtils` from order-utils instead of contracts-test-utils
2019-12-04 13:08:08 -08:00
mzhu25
b86d19028c Merge pull request #2366 from 0xProject/feature/fuzz/makers-and-takers
Pool Member Fuzz Tests
2019-12-04 11:12:55 -08:00
F. Eugene Aumson
4f17a251d3 Python publish for v3 (#2383)
* Remove pre-release suffixes from version numbers

* For wrapper test, pull latest ganache image first

* For wrapper test, unpin ganache, use beta snapshot

* In docs, advise using beta ganache snapshot

Because we haven't yet published the non-beta snapshot

* Unpin package interdependencies

* unpin tests from beta 0xorg/ganache-cli version

* use beta ganache snapshot

* Set release date in CHANGELOGs

* In testing deployment, stop testing pre-releases

* Include rmtree("build") in all clean commands

* Fix clean not cleaning what it thought it was

* In monorepo script, install pkgs 1st then dev deps

* Stop pinning ganache snapshot version

* In test setup, wait longer for mesh to start up

* Fix broken hyperlinks in docs

* fix missing \n that was breaking doc rendering

* In monorepo script comment, fix typo, and clarify
2019-12-04 08:42:00 -08:00
Michael Zhu
3d79fe2bf4 post-rebase lockfile update 2019-12-03 15:34:59 -08:00
Alex Towle
474399154f Addressed last review comment 2019-12-03 14:41:53 -08:00
Alex Towle
19f5153d0e Addressed some review feedback 2019-12-03 14:41:53 -08:00
Alex Towle
ce11271866 Appease the linter 2019-12-03 14:40:18 -08:00
Alex Towle
86cf353296 Improved the fuzz test 2019-12-03 14:40:07 -08:00
Alex Towle
36df5dc721 Implemented a hacky version of the fillOrder fuzz tests 2019-12-03 14:40:07 -08:00
Alex Towle
1e44a9c942 Made function assertions work with the new wrappers 2019-12-03 14:39:29 -08:00
mzhu25
8685cf9036 Merge pull request #2357 from 0xProject/refactor/integrations/transaction-tests
`@0x/contracts-integrations`: Transaction integration tests
2019-12-03 11:04:11 -08:00
Michael Zhu
2232870b09 address comments 2019-12-03 10:35:59 -08:00
Amir Bandeali
b68acd101e Fix failing tests 2019-12-03 08:46:47 -08:00
Amir Bandeali
173ba9b2b5 Add ChaiBridge unit tests 2019-12-02 16:42:17 -08:00
Amir Bandeali
64ed1f87d3 Rethrow custom error string if draw call fails 2019-12-02 16:42:17 -08:00
Michael Zhu
1ca085ec4a address comments 2019-12-02 15:39:03 -08:00
Michael Zhu
e332b7535c prettier 2019-12-02 15:39:02 -08:00
Michael Zhu
79eb613b3e Use AbiEncoder for methodAbiToFunctionSignature 2019-12-02 15:39:02 -08:00
Michael Zhu
5a79ec28d1 transaction protocol fee integration tests 2019-12-02 15:39:02 -08:00
Michael Zhu
97e65a02c0 fix test nesting 2019-12-02 15:39:02 -08:00
Michael Zhu
e87c786b77 fix dataItemsToABIString 2019-12-02 15:39:02 -08:00
Michael Zhu
251d30d47f refactor transaction integration tests to use new framework 2019-12-02 15:39:02 -08:00
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
7a3f878c11 Add ChaiBridge to boilerplate 2019-12-01 15:57:01 -08:00
Amir Bandeali
b8439598bc Remove redundant getters from bridges 2019-12-01 15:55:27 -08:00
Amir Bandeali
7fb0818923 Implement ChaiBridge 2019-12-01 15:54:58 -08:00
Amir Bandeali
a7c435adc4 Add mainnet deployment addresses for Dai, Chai, and ERC20BridgeProxy 2019-12-01 15:40:29 -08: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
902 changed files with 74012 additions and 125072 deletions

View File

@@ -37,7 +37,7 @@ jobs:
- store_artifacts: - store_artifacts:
path: ~/repo/packages/abi-gen/test-cli/output path: ~/repo/packages/abi-gen/test-cli/output
- store_artifacts: - store_artifacts:
path: ~/repo/packages/abi-gen-wrappers/generated_docs path: ~/repo/packages/contract-wrappers/generated_docs
test-contracts-ganache: test-contracts-ganache:
resource_class: medium+ resource_class: medium+
docker: docker:
@@ -77,7 +77,7 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- repo-{{ .Environment.CIRCLE_SHA1 }} - repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-tests @0x/contracts-staking @0x/contracts-coordinator - run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-tests @0x/contracts-staking @0x/contracts-coordinator @0x/contracts-erc20-bridge-sampler
# TODO(dorothy-zbornak): Re-enable after updating this package for # TODO(dorothy-zbornak): Re-enable after updating this package for
# 3.0. At that time, also remove exclusion from monorepo # 3.0. At that time, also remove exclusion from monorepo
# package.json's test script. # package.json's test script.
@@ -93,8 +93,8 @@ jobs:
keys: keys:
- repo-{{ .Environment.CIRCLE_SHA1 }} - repo-{{ .Environment.CIRCLE_SHA1 }}
- run: - run:
command: yarn test:publish:circleci command: yarn test:publish:circleci
no_output_timeout: 1800 no_output_timeout: 1800
test-doc-generation: test-doc-generation:
docker: docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8 - image: nikolaik/python-nodejs:python3.7-nodejs8
@@ -104,8 +104,8 @@ jobs:
keys: keys:
- repo-{{ .Environment.CIRCLE_SHA1 }} - repo-{{ .Environment.CIRCLE_SHA1 }}
- run: - run:
command: yarn test:generate_docs:circleci command: yarn test:generate_docs:circleci
no_output_timeout: 1200 no_output_timeout: 1200
test-rest: test-rest:
docker: docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8 - image: nikolaik/python-nodejs:python3.7-nodejs8
@@ -116,23 +116,16 @@ jobs:
- repo-{{ .Environment.CIRCLE_SHA1 }} - repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-test-utils - run: yarn wsrun test:circleci @0x/contracts-test-utils
- run: yarn wsrun test:circleci @0x/abi-gen - run: yarn wsrun test:circleci @0x/abi-gen
# TODO (xianny): Needs to be updated for 3.0 - run: yarn wsrun test:circleci @0x/asset-swapper
# - run: yarn wsrun test:circleci @0x/asset-buyer
# TODO: Needs to be updated for 3.0. At that time, also remove
# exclusion from monorepo package.json's test script.
# - run: yarn wsrun test:circleci @0x/asset-swapper
- run: yarn wsrun test:circleci @0x/contract-artifacts - run: yarn wsrun test:circleci @0x/contract-artifacts
- run: yarn wsrun test:circleci @0x/assert - run: yarn wsrun test:circleci @0x/assert
- run: yarn wsrun test:circleci @0x/base-contract - run: yarn wsrun test:circleci @0x/base-contract
# TODO (xianny): Needs to be updated for 3.0 - run: yarn wsrun test:circleci @0x/connect
# - run: yarn wsrun test:circleci @0x/connect - run: yarn wsrun test:circleci @0x/contract-wrappers-test
- run: yarn wsrun test:circleci @0x/contract-wrappers
- run: yarn wsrun test:circleci @0x/dev-utils - run: yarn wsrun test:circleci @0x/dev-utils
- run: yarn wsrun test:circleci @0x/json-schemas - run: yarn wsrun test:circleci @0x/json-schemas
- run: yarn wsrun test:circleci @0x/order-utils - run: yarn wsrun test:circleci @0x/order-utils
# TODO: Needs to be updated for 3.0. At that time, also remove - run: yarn wsrun test:circleci @0x/orderbook
# exclusion from monorepo package.json's test script.
# - run: yarn wsrun test:circleci @0x/orderbook
- run: yarn wsrun test:circleci @0x/sol-compiler - run: yarn wsrun test:circleci @0x/sol-compiler
- run: yarn wsrun test:circleci @0x/sol-tracing-utils - run: yarn wsrun test:circleci @0x/sol-tracing-utils
- run: yarn wsrun test:circleci @0x/sol-doc - run: yarn wsrun test:circleci @0x/sol-doc
@@ -149,9 +142,9 @@ jobs:
paths: paths:
- ~/repo/packages/assert/coverage/lcov.info - ~/repo/packages/assert/coverage/lcov.info
- save_cache: - save_cache:
key: coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }} key: coverage-asset-swapper-{{ .Environment.CIRCLE_SHA1 }}
paths: paths:
- ~/repo/packages/asset-buyer/coverage/lcov.info - ~/repo/packages/asset-swapper/coverage/lcov.info
- save_cache: - save_cache:
key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }} key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
paths: paths:
@@ -161,9 +154,9 @@ jobs:
paths: paths:
- ~/repo/packages/connect/coverage/lcov.info - ~/repo/packages/connect/coverage/lcov.info
- save_cache: - save_cache:
key: coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }} key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
paths: paths:
- ~/repo/packages/contract-wrappers/coverage/lcov.info - ~/repo/packages/contract-wrappers-test/coverage/lcov.info
- save_cache: - save_cache:
key: coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }} key: coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
paths: paths:
@@ -200,11 +193,8 @@ jobs:
working_directory: ~/repo working_directory: ~/repo
docker: docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8 - image: nikolaik/python-nodejs:python3.7-nodejs8
- image: 0xorg/ganache-cli:4.4.0-beta.1 - image: 0xorg/ganache-cli
environment: - image: 0xorg/mesh:0xV3
VERSION: 4.4.0-beta.1
SNAPSHOT_NAME: 0x_ganache_snapshot-v3-beta
- image: 0xorg/mesh:6.0.0-beta-0xv3
environment: environment:
ETHEREUM_RPC_URL: 'http://localhost:8545' ETHEREUM_RPC_URL: 'http://localhost:8545'
ETHEREUM_NETWORK_ID: '50' ETHEREUM_NETWORK_ID: '50'
@@ -219,14 +209,14 @@ jobs:
- image: 0xorg/launch-kit-backend:v3 - image: 0xorg/launch-kit-backend:v3
environment: environment:
RPC_URL: 'http://localhost:8545' RPC_URL: 'http://localhost:8545'
NETWORK_ID: 50 CHAIN_ID: 1337
WHITELIST_ALL_TOKENS: True WHITELIST_ALL_TOKENS: True
FEE_RECIPIENT: '0x0000000000000000000000000000000000000001' FEE_RECIPIENT: '0x0000000000000000000000000000000000000001'
MAKER_FEE_UNIT_AMOUNT: 0 MAKER_FEE_UNIT_AMOUNT: 0
TAKER_FEE_UNIT_AMOUNT: 0 TAKER_FEE_UNIT_AMOUNT: 0
MESH_ENDPOINT: 'ws://localhost:60557' MESH_ENDPOINT: 'ws://localhost:60557'
command: | command: |
sh -c "waitForMesh () { sleep 5; }; waitForMesh && node_modules/.bin/forever ts/lib/index.js" sh -c "waitForMesh () { sleep 30; }; waitForMesh && node_modules/.bin/forever ts/lib/index.js"
steps: steps:
- checkout - checkout
- restore_cache: - restore_cache:
@@ -369,7 +359,7 @@ jobs:
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }} - coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache: - restore_cache:
keys: keys:
- coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }} - coverage-asset-swapper-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache: - restore_cache:
keys: keys:
- coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }} - coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
@@ -378,7 +368,7 @@ jobs:
- coverage-connect-{{ .Environment.CIRCLE_SHA1 }} - coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache: - restore_cache:
keys: keys:
- coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }} - coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache: - restore_cache:
keys: keys:
- coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }} - coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}

View File

@@ -19,18 +19,15 @@ contracts: ['contracts']
@0x/sol-tracing-utils: ['packages/sol-tracing-utils'] @0x/sol-tracing-utils: ['packages/sol-tracing-utils']
@0x/utils: ['packages/utils'] @0x/utils: ['packages/utils']
@0x/tslint-config: ['packages/tslint-config'] @0x/tslint-config: ['packages/tslint-config']
@0x/asset-buyer: ['packages/asset-buyer'] @0x/asset-swapper: ['packages/asset-swapper']
@0x/order-utils: ['packages/order-utils'] @0x/order-utils: ['packages/order-utils']
@0x/assert: ['packages/assert'] @0x/assert: ['packages/assert']
@0x/base-contract: ['packages/base-contract'] @0x/base-contract: ['packages/base-contract']
@0x/typescript-typings: ['packages/typescript-typings'] @0x/typescript-typings: ['packages/typescript-typings']
0x.js: ['packages/0x.js'] 0x.js: ['packages/0x.js']
@0x/abi-gen-wrappers: ['packages/abi-gen-wrappers']
@0x/contract-artifacts: ['packages/contract-artifacts'] @0x/contract-artifacts: ['packages/contract-artifacts']
@0x/dev-utils: ['packages/dev-utils'] @0x/dev-utils: ['packages/dev-utils']
@0x/contract-wrappers: ['packages/contract-wrappers'] @0x/contract-wrappers: ['packages/contract-wrappers']
@0x/json-schemas: ['packages/json-schemas'] @0x/json-schemas: ['packages/json-schemas']
@0x/ethereum-types: ['ethereum-types'] @0x/ethereum-types: ['ethereum-types']
@0x/connect: ['packages/connect'] @0x/connect: ['packages/connect']
@0x/testnet-faucets: ['packages/testnet-faucets']
@0x/monorepo-scripts: ['packages/monorepo-scripts']

41
.gitignore vendored
View File

@@ -78,28 +78,42 @@ TODO.md
# VSCode file # VSCode file
.vscode .vscode
# server cli
packages/testnet-faucets/server/
# generated contract artifacts/ # generated contract artifacts/
contracts/erc20-bridge-sampler/generated-artifacts/
contracts/erc20-bridge-sampler/test/generated-artifacts/
contracts/integrations/generated-artifacts/ contracts/integrations/generated-artifacts/
contracts/integrations/test/generated-artifacts/
contracts/staking/generated-artifacts/ contracts/staking/generated-artifacts/
contracts/staking/test/generated-artifacts/
contracts/coordinator/generated-artifacts/ contracts/coordinator/generated-artifacts/
contracts/coordinator/test/generated-artifacts/
contracts/exchange/generated-artifacts/ contracts/exchange/generated-artifacts/
contracts/exchange/test/generated-artifacts/
contracts/asset-proxy/generated-artifacts/ contracts/asset-proxy/generated-artifacts/
contracts/asset-proxy/test/generated-artifacts/
contracts/multisig/generated-artifacts/ contracts/multisig/generated-artifacts/
contracts/multisig/test/generated-artifacts/
contracts/utils/generated-artifacts/ contracts/utils/generated-artifacts/
contracts/utils/test/generated-artifacts/
contracts/exchange-libs/generated-artifacts/ contracts/exchange-libs/generated-artifacts/
contracts/exchange-libs/test/generated-artifacts/
contracts/erc20/generated-artifacts/ contracts/erc20/generated-artifacts/
contracts/erc20/test/generated-artifacts/
contracts/erc721/generated-artifacts/ contracts/erc721/generated-artifacts/
contracts/erc721/test/generated-artifacts/
contracts/erc1155/generated-artifacts/ contracts/erc1155/generated-artifacts/
contracts/erc1155/test/generated-artifacts/
contracts/extensions/generated-artifacts/ contracts/extensions/generated-artifacts/
contracts/extensions/test/generated-artifacts/
contracts/exchange-forwarder/generated-artifacts/ contracts/exchange-forwarder/generated-artifacts/
contracts/exchange-forwarder/test/generated-artifacts/
contracts/dev-utils/generated-artifacts/ contracts/dev-utils/generated-artifacts/
contracts/dev-utils/test/generated-artifacts/
packages/sol-tracing-utils/test/fixtures/artifacts/ packages/sol-tracing-utils/test/fixtures/artifacts/
python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/ python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/
# generated truffle contract artifacts/ # generated truffle contract artifacts/
contracts/erc20-bridge-sampler/build/
contracts/staking/build/ contracts/staking/build/
contracts/coordinator/build/ contracts/coordinator/build/
contracts/exchange/build/ contracts/exchange/build/
@@ -116,20 +130,36 @@ contracts/dev-utils/build/
# generated contract wrappers # generated contract wrappers
packages/python-contract-wrappers/generated/ packages/python-contract-wrappers/generated/
contracts/erc20-bridge-sampler/generated-wrappers/
contracts/erc20-bridge-sampler/test/generated-wrappers/
contracts/integrations/generated-wrappers/ contracts/integrations/generated-wrappers/
contracts/integrations/test/generated-wrappers/
contracts/staking/generated-wrappers/ contracts/staking/generated-wrappers/
contracts/staking/test/generated-wrappers/
contracts/coordinator/generated-wrappers/ contracts/coordinator/generated-wrappers/
contracts/coordinator/test/generated-wrappers/
contracts/exchange/generated-wrappers/ contracts/exchange/generated-wrappers/
contracts/exchange/test/generated-wrappers/
contracts/asset-proxy/generated-wrappers/ contracts/asset-proxy/generated-wrappers/
contracts/asset-proxy/test/generated-wrappers/
contracts/multisig/generated-wrappers/ contracts/multisig/generated-wrappers/
contracts/multisig/test/generated-wrappers/
contracts/utils/generated-wrappers/ contracts/utils/generated-wrappers/
contracts/utils/test/generated-wrappers/
contracts/exchange-libs/generated-wrappers/ contracts/exchange-libs/generated-wrappers/
contracts/exchange-libs/test/generated-wrappers/
contracts/erc20/generated-wrappers/ contracts/erc20/generated-wrappers/
contracts/erc20/test/generated-wrappers/
contracts/erc721/generated-wrappers/ contracts/erc721/generated-wrappers/
contracts/erc721/test/generated-wrappers/
contracts/erc1155/generated-wrappers/ contracts/erc1155/generated-wrappers/
contracts/erc1155/test/generated-wrappers/
contracts/extensions/generated-wrappers/ contracts/extensions/generated-wrappers/
contracts/extensions/test/generated-wrappers/
contracts/exchange-forwarder/generated-wrappers/ contracts/exchange-forwarder/generated-wrappers/
contracts/exchange-forwarder/test/generated-wrappers/
contracts/dev-utils/generated-wrappers/ contracts/dev-utils/generated-wrappers/
contracts/dev-utils/test/generated-wrappers/
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dev_utils/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dev_utils/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py
@@ -141,19 +171,22 @@ python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dummy_erc721_tok
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dutch_auction/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dutch_auction/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_mintable/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_mintable/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_bridge_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_token/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_token/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/eth_balance_checker/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/forwarder/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/forwarder/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_asset_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_asset_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_validator/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_validator/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_wallet/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_wallet/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/multi_asset_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/multi_asset_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_validator/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_validator/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/staking/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/staking_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/static_call_proxy/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/static_call_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/weth9/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/weth9/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_token/__init__.py python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_token/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_vault/__init__.py
# solc-bin in sol-compiler # solc-bin in sol-compiler
packages/sol-compiler/solc_bin/ packages/sol-compiler/solc_bin/

View File

@@ -1,33 +1,65 @@
lib lib
.nyc_output .nyc_output
/contracts/integrations/generated-wrappers /contracts/integrations/generated-wrappers
/contracts/integrations/test/generated-wrappers
/contracts/integrations/generated-artifacts /contracts/integrations/generated-artifacts
/contracts/integrations/test/generated-artifacts
/contracts/staking/generated-wrappers /contracts/staking/generated-wrappers
/contracts/staking/test/generated-wrappers
/contracts/staking/generated-artifacts /contracts/staking/generated-artifacts
/contracts/staking/test/generated-artifacts
/contracts/coordinator/generated-wrappers /contracts/coordinator/generated-wrappers
/contracts/coordinator/test/generated-wrappers
/contracts/coordinator/generated-artifacts /contracts/coordinator/generated-artifacts
/contracts/coordinator/test/generated-artifacts
/contracts/exchange/generated-wrappers /contracts/exchange/generated-wrappers
/contracts/exchange/test/generated-wrappers
/contracts/exchange/generated-artifacts /contracts/exchange/generated-artifacts
/contracts/exchange/test/generated-artifacts
/contracts/asset-proxy/generated-wrappers /contracts/asset-proxy/generated-wrappers
/contracts/asset-proxy/test/generated-wrappers
/contracts/asset-proxy/generated-artifacts /contracts/asset-proxy/generated-artifacts
/contracts/asset-proxy/test/generated-artifacts
/contracts/multisig/generated-wrappers /contracts/multisig/generated-wrappers
/contracts/multisig/test/generated-wrappers
/contracts/multisig/generated-artifacts /contracts/multisig/generated-artifacts
/contracts/multisig/test/generated-artifacts
/contracts/utils/generated-wrappers /contracts/utils/generated-wrappers
/contracts/utils/test/generated-wrappers
/contracts/utils/generated-artifacts /contracts/utils/generated-artifacts
/contracts/utils/test/generated-artifacts
/contracts/exchange-libs/generated-wrappers /contracts/exchange-libs/generated-wrappers
/contracts/exchange-libs/test/generated-wrappers
/contracts/exchange-libs/generated-artifacts /contracts/exchange-libs/generated-artifacts
/contracts/exchange-libs/test/generated-artifacts
/contracts/erc20/generated-wrappers /contracts/erc20/generated-wrappers
/contracts/erc20/test/generated-wrappers
/contracts/erc20/generated-artifacts /contracts/erc20/generated-artifacts
/contracts/erc20/test/generated-artifacts
/contracts/erc20-bridge-sampler/generated-wrappers
/contracts/erc20-bridge-sampler/test/generated-wrappers
/contracts/erc20-bridge-sampler/generated-artifacts
/contracts/erc20-bridge-sampler/test/generated-artifacts
/contracts/erc721/generated-wrappers /contracts/erc721/generated-wrappers
/contracts/erc721/test/generated-wrappers
/contracts/erc721/generated-artifacts /contracts/erc721/generated-artifacts
/contracts/erc721/test/generated-artifacts
/contracts/erc1155/generated-wrappers /contracts/erc1155/generated-wrappers
/contracts/erc1155/test/generated-wrappers
/contracts/erc1155/generated-artifacts /contracts/erc1155/generated-artifacts
/contracts/erc1155/test/generated-artifacts
/contracts/extensions/generated-wrappers /contracts/extensions/generated-wrappers
/contracts/extensions/test/generated-wrappers
/contracts/extensions/generated-artifacts /contracts/extensions/generated-artifacts
/contracts/extensions/test/generated-artifacts
/contracts/exchange-forwarder/generated-wrappers /contracts/exchange-forwarder/generated-wrappers
/contracts/exchange-forwarder/test/generated-wrappers
/contracts/exchange-forwarder/generated-artifacts /contracts/exchange-forwarder/generated-artifacts
/contracts/exchange-forwarder/test/generated-artifacts
/contracts/dev-utils/generated-wrappers /contracts/dev-utils/generated-wrappers
/contracts/dev-utils/test/generated-wrappers
/contracts/dev-utils/generated-artifacts /contracts/dev-utils/generated-artifacts
/contracts/dev-utils/test/generated-artifacts
/contracts/staking/build/ /contracts/staking/build/
/contracts/coordinator/build/ /contracts/coordinator/build/
/contracts/exchange/build/ /contracts/exchange/build/

View File

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

View File

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

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/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/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/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/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/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/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/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 | | [`@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 #### Ethereum tooling
@@ -96,10 +94,9 @@ These packages are all under development. See [/contracts/README.md](/contracts/
#### Private Packages #### Private Packages
| Package | Description | | Package | Description |
| -------------------------------------------------- | -------------------------------------------------------------------------------- | | ---------------------------------- | -------------------------------------------------------------------------------- |
| [`@0x/instant`](/packages/instant) | A free and flexible way to offer simple crypto purchasing in any app or website. | | [`@0x/instant`](/packages/instant) | A free and flexible way to offer simple crypto purchasing in any app or website. |
| [`@0x/testnet-faucets`](/packages/testnet-faucets) | A faucet micro-service that dispenses test ERC20 tokens or Ether |
## Usage ## Usage

View File

@@ -13,4 +13,4 @@
#### Development #### Development
Building solidity files will update the contract artifact in `{package-name}/generated-artifacts/{contract}.json`, but does not automatically update the `abi-gen-wrappers` package, which are generated from the artifact JSON. To ensure consistency, clean and rebuild `abi-gen-wrappers` after any changes to the artifact JSON. Building solidity files will update the contract artifact in `{package-name}/generated-artifacts/{contract}.json`, but does not automatically update the `contract-artifacts` or `contract-wrappers` packages, which are generated from the artifact JSON. See `contract-artifacts/README.md` for instructions on updating these packages.

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,92 @@
[ [
{
"timestamp": 1575931811,
"version": "3.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "3.0.0",
"changes": [
{
"note": "Implement `KyberBridge`.",
"pr": 2352
},
{
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
"pr": 2330
},
{
"note": "ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract",
"pr": 2034
},
{
"note": "Disallow the zero address from being made an authorized address in MixinAuthorizable, and created an archive directory that includes an old version of Ownable",
"pr": 2019
},
{
"note": "Remove `LibAssetProxyIds` contract",
"pr": 2055
},
{
"note": "Compile and export all contracts, artifacts, and wrappers by default",
"pr": 2055
},
{
"note": "Remove unused dependency on IAuthorizable in IAssetProxy",
"pr": 1910
},
{
"note": "Add `ERC20BridgeProxy`",
"pr": 2220
},
{
"note": "Add `Eth2DaiBridge`",
"pr": 2221
},
{
"note": "Add `UniswapBridge`",
"pr": 2233
},
{
"note": "Replaced `SafeMath` with `LibSafeMath`",
"pr": 2254
}
],
"timestamp": 1575296764
},
{
"version": "2.3.0-beta.4",
"changes": [
{
"note": "Implement `KyberBridge`.",
"pr": 2352
}
],
"timestamp": 1575290197
},
{
"version": "2.3.0-beta.3",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1574238768
},
{
"version": "2.3.0-beta.2",
"changes": [
{
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
"pr": 2330
}
],
"timestamp": 1574030254
},
{ {
"version": "2.3.0-beta.1", "version": "2.3.0-beta.1",
"changes": [ "changes": [

View File

@@ -5,6 +5,36 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v3.0.1 - _December 9, 2019_
* Dependencies updated
## v3.0.0 - _December 2, 2019_
* Implement `KyberBridge`. (#2352)
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
* ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract (#2034)
* Disallow the zero address from being made an authorized address in MixinAuthorizable, and created an archive directory that includes an old version of Ownable (#2019)
* Remove `LibAssetProxyIds` contract (#2055)
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
* Remove unused dependency on IAuthorizable in IAssetProxy (#1910)
* Add `ERC20BridgeProxy` (#2220)
* Add `Eth2DaiBridge` (#2221)
* Add `UniswapBridge` (#2233)
* Replaced `SafeMath` with `LibSafeMath` (#2254)
## v2.3.0-beta.4 - _December 2, 2019_
* Implement `KyberBridge`. (#2352)
## v2.3.0-beta.3 - _November 20, 2019_
* Dependencies updated
## v2.3.0-beta.2 - _November 17, 2019_
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
## v2.3.0-beta.1 - _November 7, 2019_ ## v2.3.0-beta.1 - _November 7, 2019_
* ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract (#2034) * ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract (#2034)

View File

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

View File

@@ -0,0 +1,75 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "../interfaces/IERC20Bridge.sol";
import "../interfaces/IChai.sol";
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
// solhint-disable space-after-comma
contract ChaiBridge is
IERC20Bridge,
DeploymentConstants
{
/// @dev Withdraws `amount` of `from` address's Dai from the Chai contract.
/// Transfers `amount` of Dai to `to` address.
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
/// @return success The magic bytes `0x37708e9b` if successful.
function bridgeTransferFrom(
address /* tokenAddress */,
address from,
address to,
uint256 amount,
bytes calldata /* bridgeData */
)
external
returns (bytes4 success)
{
// Ensure that only the `ERC20BridgeProxy` can call this function.
require(
msg.sender == _getERC20BridgeProxyAddress(),
"ChaiBridge/ONLY_CALLABLE_BY_ERC20_BRIDGE_PROXY"
);
// Withdraw `from` address's Dai.
// NOTE: This contract must be approved to spend Chai on behalf of `from`.
bytes memory drawCalldata = abi.encodeWithSelector(
IChai(address(0)).draw.selector,
from,
amount
);
(bool success,) = _getChaiAddress().call(drawCalldata);
require(
success,
"ChaiBridge/DRAW_DAI_FAILED"
);
// Transfer Dai to `to`
// This will never fail if the `draw` call was successful
IERC20Token(_getDaiAddress()).transfer(to, amount);
return BRIDGE_SUCCESS;
}
}

View File

@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
import "../interfaces/IERC20Bridge.sol"; import "../interfaces/IERC20Bridge.sol";
import "../interfaces/IEth2Dai.sol"; import "../interfaces/IEth2Dai.sol";
@@ -29,11 +30,9 @@ import "../interfaces/IEth2Dai.sol";
// solhint-disable space-after-comma // solhint-disable space-after-comma
contract Eth2DaiBridge is contract Eth2DaiBridge is
IERC20Bridge, IERC20Bridge,
IWallet IWallet,
DeploymentConstants
{ {
/* Mainnet addresses */
address constant public ETH2DAI_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
/// `toTokenAddress` tokens by selling the entirety of the opposing asset /// `toTokenAddress` tokens by selling the entirety of the opposing asset
/// (DAI or WETH) to the Eth2Dai contract, then transfers the bought /// (DAI or WETH) to the Eth2Dai contract, then transfers the bought
@@ -56,13 +55,13 @@ contract Eth2DaiBridge is
// Decode the bridge data to get the `fromTokenAddress`. // Decode the bridge data to get the `fromTokenAddress`.
(address fromTokenAddress) = abi.decode(bridgeData, (address)); (address fromTokenAddress) = abi.decode(bridgeData, (address));
IEth2Dai exchange = _getEth2DaiContract(); IEth2Dai exchange = IEth2Dai(_getEth2DaiAddress());
// Grant an allowance to the exchange to spend `fromTokenAddress` token. // Grant an allowance to the exchange to spend `fromTokenAddress` token.
LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1)); LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1));
// Try to sell all of this contract's `fromTokenAddress` token balance. // Try to sell all of this contract's `fromTokenAddress` token balance.
uint256 boughtAmount = _getEth2DaiContract().sellAllAmount( uint256 boughtAmount = exchange.sellAllAmount(
address(fromTokenAddress), fromTokenAddress,
IERC20Token(fromTokenAddress).balanceOf(address(this)), IERC20Token(fromTokenAddress).balanceOf(address(this)),
toTokenAddress, toTokenAddress,
amount amount
@@ -85,14 +84,4 @@ contract Eth2DaiBridge is
{ {
return LEGACY_WALLET_MAGIC_VALUE; return LEGACY_WALLET_MAGIC_VALUE;
} }
/// @dev Overridable way to get the eth2dai contract.
/// @return exchange The Eth2Dai exchange contract.
function _getEth2DaiContract()
internal
view
returns (IEth2Dai exchange)
{
return IEth2Dai(ETH2DAI_ADDRESS);
}
} }

View File

@@ -0,0 +1,146 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
import "../interfaces/IERC20Bridge.sol";
import "../interfaces/IKyberNetworkProxy.sol";
// solhint-disable space-after-comma
contract KyberBridge is
IERC20Bridge,
IWallet,
DeploymentConstants
{
// @dev Structure used internally to get around stack limits.
struct TradeState {
IKyberNetworkProxy kyber;
IEtherToken weth;
address fromTokenAddress;
uint256 fromTokenBalance;
uint256 payableAmount;
}
/// @dev Kyber ETH pseudo-address.
address constant public KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/// @dev `bridgeTransferFrom()` failure result.
bytes4 constant private BRIDGE_FAILED = 0x0;
/// @dev Precision of Kyber rates.
uint256 constant private KYBER_RATE_BASE = 10 ** 18;
// solhint-disable no-empty-blocks
/// @dev Payable fallback to receive ETH from Kyber.
function ()
external
payable
{}
/// @dev Callback for `IKyberBridge`. Tries to buy `amount` of
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
/// to the `KyberNetworkProxy` contract, then transfers the bought
/// tokens to `to`.
/// @param toTokenAddress The token to give to `to`.
/// @param to The recipient of the bought tokens.
/// @param amount Minimum amount of `toTokenAddress` tokens to buy.
/// @param bridgeData The abi-encoeded "from" token address.
/// @return success The magic bytes if successful.
function bridgeTransferFrom(
address toTokenAddress,
address /* from */,
address to,
uint256 amount,
bytes calldata bridgeData
)
external
returns (bytes4 success)
{
TradeState memory state;
state.kyber = IKyberNetworkProxy(_getKyberNetworkProxyAddress());
state.weth = IEtherToken(_getWethAddress());
// Decode the bridge data to get the `fromTokenAddress`.
(state.fromTokenAddress) = abi.decode(bridgeData, (address));
state.fromTokenBalance = IERC20Token(state.fromTokenAddress).balanceOf(address(this));
if (state.fromTokenBalance == 0) {
// Return failure if no input tokens.
return BRIDGE_FAILED;
}
if (state.fromTokenAddress == toTokenAddress) {
// Just transfer the tokens if they're the same.
LibERC20Token.transfer(state.fromTokenAddress, to, state.fromTokenBalance);
return BRIDGE_SUCCESS;
} else if (state.fromTokenAddress != address(state.weth)) {
// If the input token is not WETH, grant an allowance to the exchange
// to spend them.
LibERC20Token.approve(state.fromTokenAddress, address(state.kyber), uint256(-1));
} else {
// If the input token is WETH, unwrap it and attach it to the call.
state.fromTokenAddress = KYBER_ETH_ADDRESS;
state.payableAmount = state.fromTokenBalance;
state.weth.withdraw(state.fromTokenBalance);
}
bool isToTokenWeth = toTokenAddress == address(state.weth);
// Try to sell all of this contract's input token balance through
// `KyberNetworkProxy.trade()`.
uint256 boughtAmount = state.kyber.trade.value(state.payableAmount)(
// Input token.
state.fromTokenAddress,
// Sell amount.
state.fromTokenBalance,
// Output token.
isToTokenWeth ? KYBER_ETH_ADDRESS : toTokenAddress,
// Transfer to this contract if converting to ETH, otherwise
// transfer directly to the recipient.
isToTokenWeth ? address(uint160(address(this))) : address(uint160(to)),
// Buy as much as possible.
uint256(-1),
// Compute the minimum conversion rate, which is expressed in units with
// 18 decimal places.
(KYBER_RATE_BASE * amount) / state.fromTokenBalance,
// No affiliate address.
address(0)
);
// Wrap ETH output and transfer to recipient.
if (isToTokenWeth) {
state.weth.deposit.value(boughtAmount)();
state.weth.transfer(to, boughtAmount);
}
return BRIDGE_SUCCESS;
}
/// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker
/// and sign for itself in orders. Always succeeds.
/// @return magicValue Magic success bytes, always.
function isValidSignature(
bytes32,
bytes calldata
)
external
view
returns (bytes4 magicValue)
{
return LEGACY_WALLET_MAGIC_VALUE;
}
}

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/interfaces/IEtherToken.sol";
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
import "../interfaces/IUniswapExchangeFactory.sol"; import "../interfaces/IUniswapExchangeFactory.sol";
import "../interfaces/IUniswapExchange.sol"; import "../interfaces/IUniswapExchange.sol";
import "../interfaces/IERC20Bridge.sol"; import "../interfaces/IERC20Bridge.sol";
@@ -32,12 +33,9 @@ import "../interfaces/IERC20Bridge.sol";
// solhint-disable not-rely-on-time // solhint-disable not-rely-on-time
contract UniswapBridge is contract UniswapBridge is
IERC20Bridge, IERC20Bridge,
IWallet IWallet,
DeploymentConstants
{ {
/* Mainnet addresses */
address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
address constant private WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// Struct to hold `bridgeTransferFrom()` local variables in memory and to avoid // Struct to hold `bridgeTransferFrom()` local variables in memory and to avoid
// stack overflows. // stack overflows.
struct WithdrawToState { struct WithdrawToState {
@@ -90,7 +88,7 @@ contract UniswapBridge is
// Get our balance of `fromTokenAddress` token. // Get our balance of `fromTokenAddress` token.
state.fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this)); state.fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this));
// Get the weth contract. // Get the weth contract.
state.weth = getWethContract(); state.weth = IEtherToken(_getWethAddress());
// Convert from WETH to a token. // Convert from WETH to a token.
if (fromTokenAddress == address(state.weth)) { if (fromTokenAddress == address(state.weth)) {
@@ -163,26 +161,6 @@ contract UniswapBridge is
return LEGACY_WALLET_MAGIC_VALUE; return LEGACY_WALLET_MAGIC_VALUE;
} }
/// @dev Overridable way to get the weth contract.
/// @return token The WETH contract.
function getWethContract()
public
view
returns (IEtherToken token)
{
return IEtherToken(WETH_ADDRESS);
}
/// @dev Overridable way to get the uniswap exchange factory contract.
/// @return factory The exchange factory contract.
function getUniswapExchangeFactoryContract()
public
view
returns (IUniswapExchangeFactory factory)
{
return IUniswapExchangeFactory(UNISWAP_EXCHANGE_FACTORY_ADDRESS);
}
/// @dev Grants an unlimited allowance to the exchange for its token /// @dev Grants an unlimited allowance to the exchange for its token
/// on behalf of this contract. /// on behalf of this contract.
/// @param exchange The Uniswap token exchange. /// @param exchange The Uniswap token exchange.
@@ -209,10 +187,13 @@ contract UniswapBridge is
{ {
address exchangeTokenAddress = fromTokenAddress; address exchangeTokenAddress = fromTokenAddress;
// Whichever isn't WETH is the exchange token. // Whichever isn't WETH is the exchange token.
if (fromTokenAddress == address(getWethContract())) { if (fromTokenAddress == _getWethAddress()) {
exchangeTokenAddress = toTokenAddress; exchangeTokenAddress = toTokenAddress;
} }
exchange = getUniswapExchangeFactoryContract().getExchange(exchangeTokenAddress); exchange = IUniswapExchange(
IUniswapExchangeFactory(_getUniswapExchangeFactoryAddress())
.getExchange(exchangeTokenAddress)
);
require(address(exchange) != address(0), "NO_UNISWAP_EXCHANGE_FOR_TOKEN"); require(address(exchange) != address(0), "NO_UNISWAP_EXCHANGE_FOR_TOKEN");
return exchange; return exchange;
} }

View File

@@ -0,0 +1,33 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
// The actual Chai contract can be found here: https://github.com/dapphub/chai
contract IChai {
/// @dev Withdraws Dai owned by `src`
/// @param src Address that owns Dai.
/// @param wad Amount of Dai to withdraw.
function draw(
address src,
uint256 wad
)
external;
}

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 external
returns (uint256 tokensBought); returns (uint256 tokensBought);
/// @dev Retrieves the token that is associated with this exchange.
/// @return tokenAddress The token address.
function toTokenAddress()
external
view
returns (address tokenAddress);
} }

View File

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

View File

@@ -0,0 +1,80 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "../src/bridges/ChaiBridge.sol";
import "@0x/contracts-erc20/contracts/src/ERC20Token.sol";
contract TestChaiDai is
ERC20Token
{
address private constant ALWAYS_REVERT_ADDRESS = address(1);
function draw(
address from,
uint256 amount
)
external
{
if (from == ALWAYS_REVERT_ADDRESS) {
revert();
}
balances[msg.sender] += amount;
}
}
contract TestChaiBridge is
ChaiBridge
{
address public testChaiDai;
address private constant ALWAYS_REVERT_ADDRESS = address(1);
constructor()
public
{
testChaiDai = address(new TestChaiDai());
}
function _getDaiAddress()
internal
view
returns (address)
{
return testChaiDai;
}
function _getChaiAddress()
internal
view
returns (address)
{
return testChaiDai;
}
function _getERC20BridgeProxyAddress()
internal
view
returns (address)
{
return msg.sender == ALWAYS_REVERT_ADDRESS ? address(0) : msg.sender;
}
}

View File

@@ -192,11 +192,11 @@ contract TestEth2DaiBridge is
} }
// @dev This contract will double as the Eth2Dai contract. // @dev This contract will double as the Eth2Dai contract.
function _getEth2DaiContract() function _getEth2DaiAddress()
internal internal
view view
returns (IEth2Dai) returns (address)
{ {
return IEth2Dai(address(this)); return address(this);
} }
} }

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 _getKyberNetworkProxyAddress()
internal
view
returns (address)
{
return address(this);
}
// @dev overridden to point to test WETH.
function _getWethAddress()
internal
view
returns (address)
{
return address(weth);
}
}

View File

@@ -407,26 +407,26 @@ contract TestUniswapBridge is
function getExchange(address tokenAddress) function getExchange(address tokenAddress)
external external
view view
returns (IUniswapExchange) returns (address)
{ {
return IUniswapExchange(_testExchanges[tokenAddress]); return address(_testExchanges[tokenAddress]);
} }
// @dev Use `wethToken`. // @dev Use `wethToken`.
function getWethContract() function _getWethAddress()
public internal
view view
returns (IEtherToken) returns (address)
{ {
return IEtherToken(address(wethToken)); return address(wethToken);
} }
// @dev This contract will double as the Uniswap contract. // @dev This contract will double as the Uniswap contract.
function getUniswapExchangeFactoryContract() function _getUniswapExchangeFactoryAddress()
public internal
view view
returns (IUniswapExchangeFactory) returns (address)
{ {
return IUniswapExchangeFactory(address(this)); return address(this);
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-asset-proxy", "name": "@0x/contracts-asset-proxy",
"version": "2.3.0-beta.1", "version": "3.0.1",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -12,7 +12,7 @@
"scripts": { "scripts": {
"build": "yarn pre_build && tsc -b", "build": "yarn pre_build && tsc -b",
"build:ci": "yarn build", "build:ci": "yarn build",
"pre_build": "run-s compile contracts:gen generate_contract_wrappers", "pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
"test": "yarn run_mocha", "test": "yarn run_mocha",
"rebuild_and_test": "run-s build test", "rebuild_and_test": "run-s build test",
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
@@ -21,21 +21,25 @@
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit", "run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile": "sol-compiler", "compile": "sol-compiler",
"watch": "sol-compiler -w", "watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers", "clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers", "generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", "lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", "fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text", "coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html", "coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html", "profiler:report:html": "istanbul report html && open coverage/index.html",
"coverage:report:lcov": "istanbul report lcov", "coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test", "test:circleci": "yarn test",
"contracts:gen": "contracts-gen", "contracts:gen": "contracts-gen generate",
"contracts:copy": "contracts-gen copy",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol", "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
"compile:truffle": "truffle compile" "compile:truffle": "truffle compile",
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
}, },
"config": { "config": {
"abis": "./generated-artifacts/@(ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IERC20Bridge|IEth2Dai|IUniswapExchange|IUniswapExchangeFactory|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestERC20Bridge|TestEth2DaiBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json", "publicInterfaceContracts": "ERC1155Proxy,ERC20Proxy,ERC721Proxy,MultiAssetProxy,StaticCallProxy,ERC20BridgeProxy,Eth2DaiBridge,IAssetData,IAssetProxy,UniswapBridge,KyberBridge,ChaiBridge,TestStaticCallTarget",
"abis": "./test/generated-artifacts/@(ChaiBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IChai|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
}, },
"repository": { "repository": {
@@ -48,12 +52,15 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
"devDependencies": { "devDependencies": {
"@0x/abi-gen": "^4.4.0-beta.1", "@0x/abi-gen": "^5.0.1",
"@0x/contracts-gen": "^1.1.0-beta.1", "@0x/contracts-gen": "^2.0.1",
"@0x/contracts-test-utils": "^3.2.0-beta.1", "@0x/contracts-test-utils": "^5.0.0",
"@0x/dev-utils": "^2.4.0-beta.1", "@0x/contracts-utils": "^4.0.1",
"@0x/sol-compiler": "^3.2.0-beta.1", "@0x/dev-utils": "^3.0.1",
"@0x/tslint-config": "^3.1.0-beta.1", "@0x/sol-compiler": "^4.0.1",
"@0x/ts-doc-gen": "^0.0.22",
"@0x/tslint-config": "^4.0.0",
"@0x/types": "^3.1.0",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7", "@types/mocha": "^5.2.7",
"@types/node": "*", "@types/node": "*",
@@ -61,6 +68,7 @@
"chai-as-promised": "^7.1.0", "chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0", "chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1", "dirty-chai": "^2.0.1",
"ethereumjs-util": "^5.1.1",
"make-promises-safe": "^1.1.0", "make-promises-safe": "^1.1.0",
"mocha": "^6.2.0", "mocha": "^6.2.0",
"npm-run-all": "^4.1.2", "npm-run-all": "^4.1.2",
@@ -68,22 +76,20 @@
"solhint": "^1.4.1", "solhint": "^1.4.1",
"truffle": "^5.0.32", "truffle": "^5.0.32",
"tslint": "5.11.0", "tslint": "5.11.0",
"typedoc": "^0.15.0",
"typescript": "3.0.1" "typescript": "3.0.1"
}, },
"dependencies": { "dependencies": {
"@0x/base-contract": "^5.5.0-beta.1", "@0x/base-contract": "^6.0.1",
"@0x/contracts-dev-utils": "^0.1.0-beta.1", "@0x/contracts-dev-utils": "^1.0.1",
"@0x/contracts-erc1155": "^1.2.0-beta.1", "@0x/contracts-erc1155": "^2.0.1",
"@0x/contracts-erc20": "^2.3.0-beta.1", "@0x/contracts-erc20": "^3.0.1",
"@0x/contracts-erc721": "^2.2.0-beta.1", "@0x/contracts-erc721": "^3.0.1",
"@0x/contracts-utils": "^3.3.0-beta.1", "@0x/order-utils": "^10.0.0",
"@0x/order-utils": "^8.5.0-beta.1", "@0x/typescript-typings": "^5.0.0",
"@0x/types": "^2.5.0-beta.1", "@0x/utils": "^5.1.0",
"@0x/typescript-typings": "^4.4.0-beta.1", "@0x/web3-wrapper": "^7.0.1",
"@0x/utils": "^4.6.0-beta.1", "ethereum-types": "^3.0.0",
"@0x/web3-wrapper": "^6.1.0-beta.1",
"ethereum-types": "^2.2.0-beta.1",
"ethereumjs-util": "^5.1.1",
"lodash": "^4.17.11" "lodash": "^4.17.11"
}, },
"publishConfig": { "publishConfig": {

View File

@@ -5,6 +5,7 @@
*/ */
import { ContractArtifact } from 'ethereum-types'; import { ContractArtifact } from 'ethereum-types';
import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json';
import * as ERC1155Proxy from '../generated-artifacts/ERC1155Proxy.json'; import * as ERC1155Proxy from '../generated-artifacts/ERC1155Proxy.json';
import * as ERC20BridgeProxy from '../generated-artifacts/ERC20BridgeProxy.json'; import * as ERC20BridgeProxy from '../generated-artifacts/ERC20BridgeProxy.json';
import * as ERC20Proxy from '../generated-artifacts/ERC20Proxy.json'; import * as ERC20Proxy from '../generated-artifacts/ERC20Proxy.json';
@@ -12,44 +13,23 @@ import * as ERC721Proxy from '../generated-artifacts/ERC721Proxy.json';
import * as Eth2DaiBridge from '../generated-artifacts/Eth2DaiBridge.json'; import * as Eth2DaiBridge from '../generated-artifacts/Eth2DaiBridge.json';
import * as IAssetData from '../generated-artifacts/IAssetData.json'; import * as IAssetData from '../generated-artifacts/IAssetData.json';
import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json'; import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json';
import * as IAssetProxyDispatcher from '../generated-artifacts/IAssetProxyDispatcher.json'; import * as KyberBridge from '../generated-artifacts/KyberBridge.json';
import * as IAuthorizable from '../generated-artifacts/IAuthorizable.json';
import * as IERC20Bridge from '../generated-artifacts/IERC20Bridge.json';
import * as IEth2Dai from '../generated-artifacts/IEth2Dai.json';
import * as IUniswapExchange from '../generated-artifacts/IUniswapExchange.json';
import * as IUniswapExchangeFactory from '../generated-artifacts/IUniswapExchangeFactory.json';
import * as MixinAssetProxyDispatcher from '../generated-artifacts/MixinAssetProxyDispatcher.json';
import * as MixinAuthorizable from '../generated-artifacts/MixinAuthorizable.json';
import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json'; import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json';
import * as Ownable from '../generated-artifacts/Ownable.json';
import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json'; import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json';
import * as TestERC20Bridge from '../generated-artifacts/TestERC20Bridge.json';
import * as TestEth2DaiBridge from '../generated-artifacts/TestEth2DaiBridge.json';
import * as TestStaticCallTarget from '../generated-artifacts/TestStaticCallTarget.json'; import * as TestStaticCallTarget from '../generated-artifacts/TestStaticCallTarget.json';
import * as TestUniswapBridge from '../generated-artifacts/TestUniswapBridge.json';
import * as UniswapBridge from '../generated-artifacts/UniswapBridge.json'; import * as UniswapBridge from '../generated-artifacts/UniswapBridge.json';
export const artifacts = { export const artifacts = {
MixinAssetProxyDispatcher: MixinAssetProxyDispatcher as ContractArtifact,
MixinAuthorizable: MixinAuthorizable as ContractArtifact,
Ownable: Ownable as ContractArtifact,
ERC1155Proxy: ERC1155Proxy as ContractArtifact, ERC1155Proxy: ERC1155Proxy as ContractArtifact,
ERC20BridgeProxy: ERC20BridgeProxy as ContractArtifact,
ERC20Proxy: ERC20Proxy as ContractArtifact, ERC20Proxy: ERC20Proxy as ContractArtifact,
ERC721Proxy: ERC721Proxy as ContractArtifact, ERC721Proxy: ERC721Proxy as ContractArtifact,
MultiAssetProxy: MultiAssetProxy as ContractArtifact, MultiAssetProxy: MultiAssetProxy as ContractArtifact,
StaticCallProxy: StaticCallProxy as ContractArtifact, StaticCallProxy: StaticCallProxy as ContractArtifact,
ERC20BridgeProxy: ERC20BridgeProxy as ContractArtifact,
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact, Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
UniswapBridge: UniswapBridge as ContractArtifact,
IAssetData: IAssetData as ContractArtifact, IAssetData: IAssetData as ContractArtifact,
IAssetProxy: IAssetProxy as ContractArtifact, IAssetProxy: IAssetProxy as ContractArtifact,
IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact, UniswapBridge: UniswapBridge as ContractArtifact,
IAuthorizable: IAuthorizable as ContractArtifact, KyberBridge: KyberBridge as ContractArtifact,
IERC20Bridge: IERC20Bridge as ContractArtifact, ChaiBridge: ChaiBridge as ContractArtifact,
IEth2Dai: IEth2Dai as ContractArtifact,
IUniswapExchange: IUniswapExchange as ContractArtifact,
IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact,
TestERC20Bridge: TestERC20Bridge as ContractArtifact,
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
TestStaticCallTarget: TestStaticCallTarget as ContractArtifact, TestStaticCallTarget: TestStaticCallTarget as ContractArtifact,
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
}; };

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,64 @@
export * from './artifacts'; export { artifacts } from './artifacts';
export * from './wrappers'; export {
export * from '../test/utils'; ERC1155ProxyContract,
ERC20BridgeProxyContract,
ERC20ProxyContract,
ERC721ProxyContract,
Eth2DaiBridgeContract,
IAssetDataContract,
IAssetProxyContract,
MultiAssetProxyContract,
StaticCallProxyContract,
TestStaticCallTargetContract,
UniswapBridgeContract,
} from './wrappers';
export { ERC20Wrapper } from './erc20_wrapper';
export { ERC721Wrapper } from './erc721_wrapper';
export { ERC1155ProxyWrapper } from './erc1155_proxy_wrapper';
export { ERC1155MintableContract, Erc1155Wrapper } from '@0x/contracts-erc1155';
export { DummyERC20TokenContract } from '@0x/contracts-erc20';
export { DummyERC721TokenContract } from '@0x/contracts-erc721';
export {
ERC1155HoldingsByOwner,
ERC20BalancesByOwner,
ERC721TokenIdsByOwner,
ERC1155FungibleHoldingsByOwner,
ERC1155NonFungibleHoldingsByOwner,
} from '@0x/contracts-test-utils';
export {
TransactionReceiptWithDecodedLogs,
Provider,
ZeroExProvider,
JSONRPCRequestPayload,
JSONRPCErrorCallback,
TransactionReceiptStatus,
JSONRPCResponsePayload,
JSONRPCResponseError,
ContractArtifact,
ContractChains,
CompilerOpts,
StandardContractOutput,
CompilerSettings,
ContractChainData,
ContractAbi,
DevdocOutput,
EvmOutput,
CompilerSettingsMetadata,
OptimizerSettings,
OutputField,
ParamDescription,
EvmBytecodeOutput,
AbiDefinition,
FunctionAbi,
EventAbi,
RevertErrorAbi,
EventParameter,
DataItem,
MethodAbi,
ConstructorAbi,
FallbackAbi,
ConstructorStateMutability,
TupleDataItem,
StateMutability,
} from 'ethereum-types';

View File

@@ -3,6 +3,7 @@
* Warning: This file is auto-generated by contracts-gen. Don't edit manually. * Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
*/ */
export * from '../generated-wrappers/chai_bridge';
export * from '../generated-wrappers/erc1155_proxy'; export * from '../generated-wrappers/erc1155_proxy';
export * from '../generated-wrappers/erc20_bridge_proxy'; export * from '../generated-wrappers/erc20_bridge_proxy';
export * from '../generated-wrappers/erc20_proxy'; export * from '../generated-wrappers/erc20_proxy';
@@ -10,19 +11,8 @@ export * from '../generated-wrappers/erc721_proxy';
export * from '../generated-wrappers/eth2_dai_bridge'; export * from '../generated-wrappers/eth2_dai_bridge';
export * from '../generated-wrappers/i_asset_data'; export * from '../generated-wrappers/i_asset_data';
export * from '../generated-wrappers/i_asset_proxy'; export * from '../generated-wrappers/i_asset_proxy';
export * from '../generated-wrappers/i_asset_proxy_dispatcher'; export * from '../generated-wrappers/kyber_bridge';
export * from '../generated-wrappers/i_authorizable';
export * from '../generated-wrappers/i_erc20_bridge';
export * from '../generated-wrappers/i_eth2_dai';
export * from '../generated-wrappers/i_uniswap_exchange';
export * from '../generated-wrappers/i_uniswap_exchange_factory';
export * from '../generated-wrappers/mixin_asset_proxy_dispatcher';
export * from '../generated-wrappers/mixin_authorizable';
export * from '../generated-wrappers/multi_asset_proxy'; export * from '../generated-wrappers/multi_asset_proxy';
export * from '../generated-wrappers/ownable';
export * from '../generated-wrappers/static_call_proxy'; export * from '../generated-wrappers/static_call_proxy';
export * from '../generated-wrappers/test_erc20_bridge';
export * from '../generated-wrappers/test_eth2_dai_bridge';
export * from '../generated-wrappers/test_static_call_target'; export * from '../generated-wrappers/test_static_call_target';
export * from '../generated-wrappers/test_uniswap_bridge';
export * from '../generated-wrappers/uniswap_bridge'; export * from '../generated-wrappers/uniswap_bridge';

View File

@@ -0,0 +1,67 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
import { ContractArtifact } from 'ethereum-types';
import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json';
import * as ERC1155Proxy from '../test/generated-artifacts/ERC1155Proxy.json';
import * as ERC20BridgeProxy from '../test/generated-artifacts/ERC20BridgeProxy.json';
import * as ERC20Proxy from '../test/generated-artifacts/ERC20Proxy.json';
import * as ERC721Proxy from '../test/generated-artifacts/ERC721Proxy.json';
import * as Eth2DaiBridge from '../test/generated-artifacts/Eth2DaiBridge.json';
import * as IAssetData from '../test/generated-artifacts/IAssetData.json';
import * as IAssetProxy from '../test/generated-artifacts/IAssetProxy.json';
import * as IAssetProxyDispatcher from '../test/generated-artifacts/IAssetProxyDispatcher.json';
import * as IAuthorizable from '../test/generated-artifacts/IAuthorizable.json';
import * as IChai from '../test/generated-artifacts/IChai.json';
import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json';
import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json';
import * as IKyberNetworkProxy from '../test/generated-artifacts/IKyberNetworkProxy.json';
import * as IUniswapExchange from '../test/generated-artifacts/IUniswapExchange.json';
import * as IUniswapExchangeFactory from '../test/generated-artifacts/IUniswapExchangeFactory.json';
import * as KyberBridge from '../test/generated-artifacts/KyberBridge.json';
import * as MixinAssetProxyDispatcher from '../test/generated-artifacts/MixinAssetProxyDispatcher.json';
import * as MixinAuthorizable from '../test/generated-artifacts/MixinAuthorizable.json';
import * as MultiAssetProxy from '../test/generated-artifacts/MultiAssetProxy.json';
import * as Ownable from '../test/generated-artifacts/Ownable.json';
import * as StaticCallProxy from '../test/generated-artifacts/StaticCallProxy.json';
import * as TestChaiBridge from '../test/generated-artifacts/TestChaiBridge.json';
import * as TestERC20Bridge from '../test/generated-artifacts/TestERC20Bridge.json';
import * as TestEth2DaiBridge from '../test/generated-artifacts/TestEth2DaiBridge.json';
import * as TestKyberBridge from '../test/generated-artifacts/TestKyberBridge.json';
import * as TestStaticCallTarget from '../test/generated-artifacts/TestStaticCallTarget.json';
import * as TestUniswapBridge from '../test/generated-artifacts/TestUniswapBridge.json';
import * as UniswapBridge from '../test/generated-artifacts/UniswapBridge.json';
export const artifacts = {
MixinAssetProxyDispatcher: MixinAssetProxyDispatcher as ContractArtifact,
MixinAuthorizable: MixinAuthorizable as ContractArtifact,
Ownable: Ownable as ContractArtifact,
ERC1155Proxy: ERC1155Proxy as ContractArtifact,
ERC20BridgeProxy: ERC20BridgeProxy as ContractArtifact,
ERC20Proxy: ERC20Proxy as ContractArtifact,
ERC721Proxy: ERC721Proxy as ContractArtifact,
MultiAssetProxy: MultiAssetProxy as ContractArtifact,
StaticCallProxy: StaticCallProxy as ContractArtifact,
ChaiBridge: ChaiBridge as ContractArtifact,
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
KyberBridge: KyberBridge as ContractArtifact,
UniswapBridge: UniswapBridge as ContractArtifact,
IAssetData: IAssetData as ContractArtifact,
IAssetProxy: IAssetProxy as ContractArtifact,
IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact,
IAuthorizable: IAuthorizable as ContractArtifact,
IChai: IChai as ContractArtifact,
IERC20Bridge: IERC20Bridge as ContractArtifact,
IEth2Dai: IEth2Dai as ContractArtifact,
IKyberNetworkProxy: IKyberNetworkProxy as ContractArtifact,
IUniswapExchange: IUniswapExchange as ContractArtifact,
IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact,
TestChaiBridge: TestChaiBridge as ContractArtifact,
TestERC20Bridge: TestERC20Bridge as ContractArtifact,
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
TestKyberBridge: TestKyberBridge as ContractArtifact,
TestStaticCallTarget: TestStaticCallTarget as ContractArtifact,
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
};

View File

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

View File

@@ -0,0 +1,60 @@
import { ERC20TokenContract } from '@0x/contracts-erc20';
import { blockchainTests, constants, expect, randomAddress } from '@0x/contracts-test-utils';
import { AssetProxyId, RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { artifacts } from './artifacts';
import { TestChaiBridgeContract } from './wrappers';
blockchainTests.resets('ChaiBridge unit tests', env => {
let chaiBridgeContract: TestChaiBridgeContract;
let testDaiContract: ERC20TokenContract;
let fromAddress: string;
let toAddress: string;
const alwaysRevertAddress = '0x0000000000000000000000000000000000000001';
const amount = new BigNumber(1);
before(async () => {
[fromAddress, toAddress] = await env.getAccountAddressesAsync();
chaiBridgeContract = await TestChaiBridgeContract.deployFrom0xArtifactAsync(
artifacts.TestChaiBridge,
env.provider,
env.txDefaults,
artifacts,
);
const testChaiDaiAddress = await chaiBridgeContract.testChaiDai().callAsync();
testDaiContract = new ERC20TokenContract(testChaiDaiAddress, env.provider, env.txDefaults);
});
describe('bridgeTransferFrom()', () => {
it('fails if not called by ERC20BridgeProxy', async () => {
return expect(
chaiBridgeContract
.bridgeTransferFrom(randomAddress(), fromAddress, toAddress, amount, constants.NULL_BYTES)
.awaitTransactionSuccessAsync({ from: alwaysRevertAddress }),
).to.revertWith(RevertReason.ChaiBridgeOnlyCallableByErc20BridgeProxy);
});
it('returns magic bytes upon success', async () => {
const magicBytes = await chaiBridgeContract
.bridgeTransferFrom(randomAddress(), fromAddress, toAddress, amount, constants.NULL_BYTES)
.callAsync();
expect(magicBytes).to.eq(AssetProxyId.ERC20Bridge);
});
it('should increase the Dai balance of `toAddress` by `amount` if successful', async () => {
const initialBalance = await testDaiContract.balanceOf(toAddress).callAsync();
await chaiBridgeContract
.bridgeTransferFrom(randomAddress(), fromAddress, toAddress, amount, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const endBalance = await testDaiContract.balanceOf(toAddress).callAsync();
expect(endBalance).to.bignumber.eq(initialBalance.plus(amount));
});
it('fails if the `chai.draw` call fails', async () => {
return expect(
chaiBridgeContract
.bridgeTransferFrom(randomAddress(), alwaysRevertAddress, toAddress, amount, constants.NULL_BYTES)
.awaitTransactionSuccessAsync(),
).to.revertWith(RevertReason.ChaiBridgeDrawDaiFailed);
});
});
});

View File

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

View File

@@ -3,27 +3,22 @@ import {
constants, constants,
expect, expect,
getRandomInteger, getRandomInteger,
hexLeftPad,
hexRightPad,
hexSlice,
Numberish, Numberish,
randomAddress, randomAddress,
} from '@0x/contracts-test-utils'; } from '@0x/contracts-test-utils';
import { AuthorizableRevertErrors } from '@0x/contracts-utils';
import { AssetProxyId } from '@0x/types'; import { AssetProxyId } from '@0x/types';
import { AbiEncoder, AuthorizableRevertErrors, BigNumber, StringRevertError } from '@0x/utils'; import { AbiEncoder, BigNumber, hexUtils, StringRevertError } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types'; import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { import { artifacts } from './artifacts';
artifacts,
ERC20BridgeProxyContract, import { ERC20BridgeProxyContract, TestERC20BridgeContract } from './wrappers';
TestERC20BridgeBridgeWithdrawToEventArgs,
TestERC20BridgeContract,
} from '../src';
blockchainTests.resets('ERC20BridgeProxy unit tests', env => { blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
const PROXY_ID = AssetProxyId.ERC20Bridge; const PROXY_ID = AssetProxyId.ERC20Bridge;
const BRIDGE_SUCCESS_RETURN_DATA = hexRightPad(PROXY_ID); const BRIDGE_SUCCESS_RETURN_DATA = hexUtils.rightPad(PROXY_ID);
let owner: string; let owner: string;
let badCaller: string; let badCaller: string;
let assetProxy: ERC20BridgeProxyContract; let assetProxy: ERC20BridgeProxyContract;
@@ -44,8 +39,8 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
env.txDefaults, env.txDefaults,
artifacts, artifacts,
); );
testTokenAddress = await bridgeContract.testToken.callAsync(); testTokenAddress = await bridgeContract.testToken().callAsync();
await assetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(owner); await assetProxy.addAuthorizedAddress(owner).awaitTransactionSuccessAsync();
}); });
interface AssetDataOpts { interface AssetDataOpts {
@@ -102,7 +97,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
} }
async function setTestTokenBalanceAsync(_owner: string, balance: Numberish): Promise<void> { async function setTestTokenBalanceAsync(_owner: string, balance: Numberish): Promise<void> {
await bridgeContract.setTestTokenBalance.awaitTransactionSuccessAsync(_owner, new BigNumber(balance)); await bridgeContract.setTestTokenBalance(_owner, new BigNumber(balance)).awaitTransactionSuccessAsync();
} }
describe('transferFrom()', () => { describe('transferFrom()', () => {
@@ -132,13 +127,9 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
async function transferFromAsync(opts?: Partial<TransferFromOpts>, caller?: string): Promise<DecodedLogs> { async function transferFromAsync(opts?: Partial<TransferFromOpts>, caller?: string): Promise<DecodedLogs> {
const _opts = createTransferFromOpts(opts); const _opts = createTransferFromOpts(opts);
const { logs } = await assetProxy.transferFrom.awaitTransactionSuccessAsync( const { logs } = await assetProxy
encodeAssetData(_opts.assetData), .transferFrom(encodeAssetData(_opts.assetData), _opts.from, _opts.to, new BigNumber(_opts.amount))
_opts.from, .awaitTransactionSuccessAsync({ from: caller });
_opts.to,
new BigNumber(_opts.amount),
{ from: caller },
);
return (logs as any) as DecodedLogs; return (logs as any) as DecodedLogs;
} }
@@ -164,7 +155,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
const opts = createTransferFromOpts(); const opts = createTransferFromOpts();
const logs = await transferFromAsync(opts); const logs = await transferFromAsync(opts);
expect(logs.length).to.eq(1); expect(logs.length).to.eq(1);
const args = logs[0].args as TestERC20BridgeBridgeWithdrawToEventArgs; const args = logs[0].args;
expect(args.tokenAddress).to.eq(opts.assetData.tokenAddress); expect(args.tokenAddress).to.eq(opts.assetData.tokenAddress);
expect(args.from).to.eq(opts.from); expect(args.from).to.eq(opts.from);
expect(args.to).to.eq(opts.to); expect(args.to).to.eq(opts.to);
@@ -179,13 +170,10 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
it('fails if asset data is truncated', async () => { it('fails if asset data is truncated', async () => {
const opts = createTransferFromOpts(); const opts = createTransferFromOpts();
const truncatedAssetData = hexSlice(encodeAssetData(opts.assetData), 0, -1); const truncatedAssetData = hexUtils.slice(encodeAssetData(opts.assetData), 0, -1);
const tx = assetProxy.transferFrom.awaitTransactionSuccessAsync( const tx = assetProxy
truncatedAssetData, .transferFrom(truncatedAssetData, opts.from, opts.to, new BigNumber(opts.amount))
opts.from, .awaitTransactionSuccessAsync();
opts.to,
new BigNumber(opts.amount),
);
return expect(tx).to.be.rejected(); return expect(tx).to.be.rejected();
}); });
@@ -206,7 +194,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
const tx = transferFromAsync({ const tx = transferFromAsync({
assetData: createAssetData({ assetData: createAssetData({
bridgeData: createBridgeData({ bridgeData: createBridgeData({
returnData: hexLeftPad('0x1'), returnData: hexUtils.leftPad('0x1'),
}), }),
}), }),
}); });
@@ -219,7 +207,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
const tx = transferFromAsync({ const tx = transferFromAsync({
assetData: createAssetData({ assetData: createAssetData({
bridgeData: createBridgeData({ bridgeData: createBridgeData({
returnData: hexRightPad('0x1'), returnData: hexUtils.rightPad('0x1'),
}), }),
}), }),
}); });
@@ -281,18 +269,18 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
it('retrieves the balance of the encoded token', async () => { it('retrieves the balance of the encoded token', async () => {
const _owner = randomAddress(); const _owner = randomAddress();
const balance = getRandomInteger(1, 100e18); const balance = getRandomInteger(1, 100e18);
await bridgeContract.setTestTokenBalance.awaitTransactionSuccessAsync(_owner, balance); await bridgeContract.setTestTokenBalance(_owner, balance).awaitTransactionSuccessAsync();
const assetData = createAssetData({ const assetData = createAssetData({
tokenAddress: testTokenAddress, tokenAddress: testTokenAddress,
}); });
const actualBalance = await assetProxy.balanceOf.callAsync(encodeAssetData(assetData), _owner); const actualBalance = await assetProxy.balanceOf(encodeAssetData(assetData), _owner).callAsync();
expect(actualBalance).to.bignumber.eq(balance); expect(actualBalance).to.bignumber.eq(balance);
}); });
}); });
describe('getProxyId()', () => { describe('getProxyId()', () => {
it('returns the correct proxy ID', async () => { it('returns the correct proxy ID', async () => {
const proxyId = await assetProxy.getProxyId.callAsync(); const proxyId = await assetProxy.getProxyId().callAsync();
expect(proxyId).to.eq(PROXY_ID); expect(proxyId).to.eq(PROXY_ID);
}); });
}); });

View File

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

View File

@@ -0,0 +1,272 @@
import {
blockchainTests,
constants,
expect,
getRandomInteger,
randomAddress,
verifyEventsFromLogs,
} from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types';
import { BigNumber, hexUtils } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import { artifacts } from './artifacts';
import { TestKyberBridgeContract, TestKyberBridgeEvents } from './wrappers';
blockchainTests.resets('KyberBridge unit tests', env => {
const KYBER_ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
let testContract: TestKyberBridgeContract;
before(async () => {
testContract = await TestKyberBridgeContract.deployFrom0xArtifactAsync(
artifacts.TestKyberBridge,
env.provider,
env.txDefaults,
artifacts,
);
});
describe('isValidSignature()', () => {
it('returns success bytes', async () => {
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
const result = await testContract
.isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32)))
.callAsync();
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
});
});
describe('bridgeTransferFrom()', () => {
let fromTokenAddress: string;
let toTokenAddress: string;
let wethAddress: string;
before(async () => {
wethAddress = await testContract.weth().callAsync();
fromTokenAddress = await testContract.createToken().callAsync();
await testContract.createToken().awaitTransactionSuccessAsync();
toTokenAddress = await testContract.createToken().callAsync();
await testContract.createToken().awaitTransactionSuccessAsync();
});
const STATIC_KYBER_TRADE_ARGS = {
maxBuyTokenAmount: constants.MAX_UINT256,
walletId: constants.NULL_ADDRESS,
};
interface TransferFromOpts {
toTokenAddress: string;
fromTokenAddress: string;
toAddress: string;
// Amount to pass into `bridgeTransferFrom()`
amount: BigNumber;
// Amount to convert in `trade()`.
fillAmount: BigNumber;
// Token balance of the bridge.
fromTokenBalance: BigNumber;
}
interface TransferFromResult {
opts: TransferFromOpts;
result: string;
logs: DecodedLogs;
}
function createTransferFromOpts(opts?: Partial<TransferFromOpts>): TransferFromOpts {
return {
fromTokenAddress,
toTokenAddress,
toAddress: randomAddress(),
amount: getRandomInteger(1, 10e18),
fillAmount: getRandomInteger(1, 10e18),
fromTokenBalance: getRandomInteger(1, 10e18),
...opts,
};
}
async function withdrawToAsync(opts?: Partial<TransferFromOpts>): Promise<TransferFromResult> {
const _opts = createTransferFromOpts(opts);
// Fund the contract with input tokens.
await testContract
.grantTokensTo(_opts.fromTokenAddress, testContract.address, _opts.fromTokenBalance)
.awaitTransactionSuccessAsync({ value: _opts.fromTokenBalance });
// Fund the contract with output tokens.
await testContract.setNextFillAmount(_opts.fillAmount).awaitTransactionSuccessAsync({
value: _opts.toTokenAddress === wethAddress ? _opts.fillAmount : constants.ZERO_AMOUNT,
});
// Call bridgeTransferFrom().
const bridgeTransferFromFn = testContract.bridgeTransferFrom(
// Output token
_opts.toTokenAddress,
// Random maker address.
randomAddress(),
// Recipient address.
_opts.toAddress,
// Transfer amount.
_opts.amount,
// ABI-encode the input token address as the bridge data.
hexUtils.leftPad(_opts.fromTokenAddress),
);
const result = await bridgeTransferFromFn.callAsync();
const { logs } = await bridgeTransferFromFn.awaitTransactionSuccessAsync();
return {
opts: _opts,
result,
logs: (logs as any) as DecodedLogs,
};
}
function getMinimumConversionRate(opts: TransferFromOpts): BigNumber {
return opts.amount
.times(constants.ONE_ETHER)
.div(opts.fromTokenBalance)
.integerValue(BigNumber.ROUND_DOWN);
}
it('returns magic bytes on success', async () => {
const BRIDGE_SUCCESS_RETURN_DATA = AssetProxyId.ERC20Bridge;
const { result } = await withdrawToAsync();
expect(result).to.eq(BRIDGE_SUCCESS_RETURN_DATA);
});
it('can trade token -> token', async () => {
const { opts, logs } = await withdrawToAsync();
verifyEventsFromLogs(
logs,
[
{
sellTokenAddress: opts.fromTokenAddress,
buyTokenAddress: opts.toTokenAddress,
sellAmount: opts.fromTokenBalance,
recipientAddress: opts.toAddress,
minConversionRate: getMinimumConversionRate(opts),
msgValue: constants.ZERO_AMOUNT,
...STATIC_KYBER_TRADE_ARGS,
},
],
TestKyberBridgeEvents.KyberBridgeTrade,
);
});
it('can trade token -> ETH', async () => {
const { opts, logs } = await withdrawToAsync({
toTokenAddress: wethAddress,
});
verifyEventsFromLogs(
logs,
[
{
sellTokenAddress: opts.fromTokenAddress,
buyTokenAddress: KYBER_ETH_ADDRESS,
sellAmount: opts.fromTokenBalance,
recipientAddress: testContract.address,
minConversionRate: getMinimumConversionRate(opts),
msgValue: constants.ZERO_AMOUNT,
...STATIC_KYBER_TRADE_ARGS,
},
],
TestKyberBridgeEvents.KyberBridgeTrade,
);
});
it('can trade ETH -> token', async () => {
const { opts, logs } = await withdrawToAsync({
fromTokenAddress: wethAddress,
});
verifyEventsFromLogs(
logs,
[
{
sellTokenAddress: KYBER_ETH_ADDRESS,
buyTokenAddress: opts.toTokenAddress,
sellAmount: opts.fromTokenBalance,
recipientAddress: opts.toAddress,
minConversionRate: getMinimumConversionRate(opts),
msgValue: opts.fromTokenBalance,
...STATIC_KYBER_TRADE_ARGS,
},
],
TestKyberBridgeEvents.KyberBridgeTrade,
);
});
it('does nothing if bridge has no token balance', async () => {
const { logs } = await withdrawToAsync({
fromTokenBalance: constants.ZERO_AMOUNT,
});
expect(logs).to.be.length(0);
});
it('only transfers the token if trading the same token', async () => {
const { opts, logs } = await withdrawToAsync({
toTokenAddress: fromTokenAddress,
});
verifyEventsFromLogs(
logs,
[
{
tokenAddress: fromTokenAddress,
ownerAddress: testContract.address,
recipientAddress: opts.toAddress,
amount: opts.fromTokenBalance,
},
],
TestKyberBridgeEvents.KyberBridgeTokenTransfer,
);
});
it('grants Kyber an allowance when selling non-WETH', async () => {
const { opts, logs } = await withdrawToAsync();
verifyEventsFromLogs(
logs,
[
{
tokenAddress: opts.fromTokenAddress,
ownerAddress: testContract.address,
spenderAddress: testContract.address,
allowance: constants.MAX_UINT256,
},
],
TestKyberBridgeEvents.KyberBridgeTokenApprove,
);
});
it('does not grant Kyber an allowance when selling WETH', async () => {
const { logs } = await withdrawToAsync({
fromTokenAddress: wethAddress,
});
verifyEventsFromLogs(logs, [], TestKyberBridgeEvents.KyberBridgeTokenApprove);
});
it('withdraws WETH and passes it to Kyber when selling WETH', async () => {
const { opts, logs } = await withdrawToAsync({
fromTokenAddress: wethAddress,
});
expect(logs[0].event).to.eq(TestKyberBridgeEvents.KyberBridgeWethWithdraw);
expect(logs[0].args).to.deep.eq({
ownerAddress: testContract.address,
amount: opts.fromTokenBalance,
});
expect(logs[1].event).to.eq(TestKyberBridgeEvents.KyberBridgeTrade);
expect(logs[1].args.msgValue).to.bignumber.eq(opts.fromTokenBalance);
});
it('wraps WETH and transfers it to the recipient when buyng WETH', async () => {
const { opts, logs } = await withdrawToAsync({
toTokenAddress: wethAddress,
});
expect(logs[0].event).to.eq(TestKyberBridgeEvents.KyberBridgeTokenApprove);
expect(logs[0].args.tokenAddress).to.eq(opts.fromTokenAddress);
expect(logs[1].event).to.eq(TestKyberBridgeEvents.KyberBridgeTrade);
expect(logs[1].args.recipientAddress).to.eq(testContract.address);
expect(logs[2].event).to.eq(TestKyberBridgeEvents.KyberBridgeWethDeposit);
expect(logs[2].args).to.deep.eq({
msgValue: opts.fillAmount,
ownerAddress: testContract.address,
amount: opts.fillAmount,
});
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,9 @@ import { AbiEncoder, BigNumber } from '@0x/utils';
import * as chai from 'chai'; import * as chai from 'chai';
import * as ethUtil from 'ethereumjs-util'; import * as ethUtil from 'ethereumjs-util';
import { artifacts, IAssetProxyContract, StaticCallProxyContract, TestStaticCallTargetContract } from '../src'; import { artifacts } from './artifacts';
import { IAssetProxyContract, StaticCallProxyContract, TestStaticCallTargetContract } from './wrappers';
chaiSetup.configure(); chaiSetup.configure();
const expect = chai.expect; const expect = chai.expect;
@@ -79,26 +81,21 @@ describe('StaticCallProxy', () => {
); );
}); });
it('should have an id of 0xc339d10a', async () => { it('should have an id of 0xc339d10a', async () => {
const proxyId = await staticCallProxy.getProxyId.callAsync(); const proxyId = await staticCallProxy.getProxyId().callAsync();
const expectedProxyId = AssetProxyId.StaticCall; const expectedProxyId = AssetProxyId.StaticCall;
expect(proxyId).to.equal(expectedProxyId); expect(proxyId).to.equal(expectedProxyId);
}); });
}); });
describe('transferFrom', () => { describe('transferFrom', () => {
it('should revert if assetData lies outside the bounds of calldata', async () => { it('should revert if assetData lies outside the bounds of calldata', async () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); const staticCallData = staticCallTarget.noInputFunction().getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL; const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash, const txData = staticCallProxy
); .transferFrom(assetData, fromAddress, toAddress, amount)
const txData = staticCallProxy.transferFrom.getABIEncodedTransactionData( .getABIEncodedTransactionData();
assetData,
fromAddress,
toAddress,
amount,
);
const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080'; const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080';
const txDataEndBuffer = ethUtil.toBuffer((txData.length - 2) / 2 - 4); const txDataEndBuffer = ethUtil.toBuffer((txData.length - 2) / 2 - 4);
const paddedTxDataEndBuffer = ethUtil.setLengthLeft(txDataEndBuffer, 32); const paddedTxDataEndBuffer = ethUtil.setLengthLeft(txDataEndBuffer, 32);
@@ -116,25 +113,21 @@ describe('StaticCallProxy', () => {
it('should revert if the length of assetData is less than 100 bytes', async () => { it('should revert if the length of assetData is less than 100 bytes', async () => {
const staticCallData = constants.NULL_BYTES; const staticCallData = constants.NULL_BYTES;
const expectedResultHash = constants.KECCAK256_NULL; const expectedResultHash = constants.KECCAK256_NULL;
const assetData = (await devUtils.encodeStaticCallAssetData.callAsync( const assetData = (await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync()).slice(0, -128);
expectedResultHash,
)).slice(0, -128);
const assetDataByteLen = (assetData.length - 2) / 2; const assetDataByteLen = (assetData.length - 2) / 2;
expect((assetDataByteLen - 4) % 32).to.equal(0); expect((assetDataByteLen - 4) % 32).to.equal(0);
await expectTransactionFailedWithoutReasonAsync( await expectTransactionFailedWithoutReasonAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount), staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
); );
}); });
it('should revert if the offset to `staticCallData` points to outside of assetData', async () => { it('should revert if the offset to `staticCallData` points to outside of assetData', async () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); const staticCallData = staticCallTarget.noInputFunction().getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL; const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash,
);
const offsetToStaticCallData = '0000000000000000000000000000000000000000000000000000000000000060'; const offsetToStaticCallData = '0000000000000000000000000000000000000000000000000000000000000060';
const assetDataEndBuffer = ethUtil.toBuffer((assetData.length - 2) / 2 - 4); const assetDataEndBuffer = ethUtil.toBuffer((assetData.length - 2) / 2 - 4);
const paddedAssetDataEndBuffer = ethUtil.setLengthLeft(assetDataEndBuffer, 32); const paddedAssetDataEndBuffer = ethUtil.setLengthLeft(assetDataEndBuffer, 32);
@@ -145,94 +138,88 @@ describe('StaticCallProxy', () => {
invalidOffsetToStaticCallData, invalidOffsetToStaticCallData,
)}${newStaticCallData}`; )}${newStaticCallData}`;
await expectTransactionFailedWithoutReasonAsync( await expectTransactionFailedWithoutReasonAsync(
staticCallProxy.transferFrom.sendTransactionAsync(badAssetData, fromAddress, toAddress, amount), staticCallProxy.transferFrom(badAssetData, fromAddress, toAddress, amount).sendTransactionAsync(),
); );
}); });
it('should revert if the callTarget attempts to write to state', async () => { it('should revert if the callTarget attempts to write to state', async () => {
const staticCallData = staticCallTarget.updateState.getABIEncodedTransactionData(); const staticCallData = staticCallTarget.updateState().getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL; const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash,
);
await expectTransactionFailedWithoutReasonAsync( await expectTransactionFailedWithoutReasonAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount), staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
); );
}); });
it('should revert with data provided by the callTarget if the staticcall reverts', async () => { it('should revert with data provided by the callTarget if the staticcall reverts', async () => {
const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1)); const staticCallData = staticCallTarget.assertEvenNumber(new BigNumber(1)).getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL; const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash,
);
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount), staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
RevertReason.TargetNotEven, RevertReason.TargetNotEven,
); );
}); });
it('should revert if the hash of the output is different than expected expected', async () => { it('should revert if the hash of the output is different than expected expected', async () => {
const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0)); const staticCallData = staticCallTarget.isOddNumber(new BigNumber(0)).getABIEncodedTransactionData();
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash,
);
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount), staticCallProxy.transferFrom(assetData, fromAddress, toAddress, amount).sendTransactionAsync(),
RevertReason.UnexpectedStaticCallResult, RevertReason.UnexpectedStaticCallResult,
); );
}); });
it('should be successful if a function call with no inputs and no outputs is successful', async () => { it('should be successful if a function call with no inputs and no outputs is successful', async () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); const staticCallData = staticCallTarget.noInputFunction().getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL; const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash, await staticCallProxy
); .transferFrom(assetData, fromAddress, toAddress, amount)
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); .awaitTransactionSuccessAsync();
}); });
it('should be successful if the staticCallTarget is not a contract and no return value is expected', async () => { it('should be successful if the staticCallTarget is not a contract and no return value is expected', async () => {
const staticCallData = '0x0102030405060708'; const staticCallData = '0x0102030405060708';
const expectedResultHash = constants.KECCAK256_NULL; const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
toAddress, .encodeStaticCallAssetData(toAddress, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash, await staticCallProxy
); .transferFrom(assetData, fromAddress, toAddress, amount)
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); .awaitTransactionSuccessAsync();
}); });
it('should be successful if a function call with one static input returns the correct value', async () => { it('should be successful if a function call with one static input returns the correct value', async () => {
const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(1)); const staticCallData = staticCallTarget.isOddNumber(new BigNumber(1)).getABIEncodedTransactionData();
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash, await staticCallProxy
); .transferFrom(assetData, fromAddress, toAddress, amount)
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); .awaitTransactionSuccessAsync();
}); });
it('should be successful if a function with one dynamic input is successful', async () => { it('should be successful if a function with one dynamic input is successful', async () => {
const dynamicInput = '0x0102030405060708'; const dynamicInput = '0x0102030405060708';
const staticCallData = staticCallTarget.dynamicInputFunction.getABIEncodedTransactionData(dynamicInput); const staticCallData = staticCallTarget.dynamicInputFunction(dynamicInput).getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL; const expectedResultHash = constants.KECCAK256_NULL;
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash, await staticCallProxy
); .transferFrom(assetData, fromAddress, toAddress, amount)
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); .awaitTransactionSuccessAsync();
}); });
it('should be successful if a function call returns a complex type', async () => { it('should be successful if a function call returns a complex type', async () => {
const a = new BigNumber(1); const a = new BigNumber(1);
const b = new BigNumber(2); const b = new BigNumber(2);
const staticCallData = staticCallTarget.returnComplexType.getABIEncodedTransactionData(a, b); const staticCallData = staticCallTarget.returnComplexType(a, b).getABIEncodedTransactionData();
const abiEncoder = new AbiEncoder.DynamicBytes({ const abiEncoder = new AbiEncoder.DynamicBytes({
name: '', name: '',
type: 'bytes', type: 'bytes',
@@ -245,12 +232,12 @@ describe('StaticCallProxy', () => {
const expectedResultHash = ethUtil.bufferToHex( const expectedResultHash = ethUtil.bufferToHex(
ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)), ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)),
); );
const assetData = await devUtils.encodeStaticCallAssetData.callAsync( const assetData = await devUtils
staticCallTarget.address, .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
staticCallData, .callAsync();
expectedResultHash, await staticCallProxy
); .transferFrom(assetData, fromAddress, toAddress, amount)
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); .awaitTransactionSuccessAsync();
}); });
}); });
}); });

View File

@@ -5,19 +5,17 @@ import {
filterLogs, filterLogs,
filterLogsToArguments, filterLogsToArguments,
getRandomInteger, getRandomInteger,
hexLeftPad,
hexRandom,
Numberish, Numberish,
randomAddress, randomAddress,
TransactionHelper,
} from '@0x/contracts-test-utils'; } from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types'; import { AssetProxyId } from '@0x/types';
import { BigNumber } from '@0x/utils'; import { BigNumber, hexUtils } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types'; import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { artifacts } from './artifacts';
import { import {
artifacts,
TestUniswapBridgeContract, TestUniswapBridgeContract,
TestUniswapBridgeEthToTokenTransferInputEventArgs as EthToTokenTransferInputArgs, TestUniswapBridgeEthToTokenTransferInputEventArgs as EthToTokenTransferInputArgs,
TestUniswapBridgeEvents as ContractEvents, TestUniswapBridgeEvents as ContractEvents,
@@ -27,10 +25,9 @@ import {
TestUniswapBridgeTokenTransferEventArgs as TokenTransferArgs, TestUniswapBridgeTokenTransferEventArgs as TokenTransferArgs,
TestUniswapBridgeWethDepositEventArgs as WethDepositArgs, TestUniswapBridgeWethDepositEventArgs as WethDepositArgs,
TestUniswapBridgeWethWithdrawEventArgs as WethWithdrawArgs, TestUniswapBridgeWethWithdrawEventArgs as WethWithdrawArgs,
} from '../src'; } from './wrappers';
blockchainTests.resets('UniswapBridge unit tests', env => { blockchainTests.resets('UniswapBridge unit tests', env => {
const txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
let testContract: TestUniswapBridgeContract; let testContract: TestUniswapBridgeContract;
let wethTokenAddress: string; let wethTokenAddress: string;
@@ -41,13 +38,15 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
env.txDefaults, env.txDefaults,
artifacts, artifacts,
); );
wethTokenAddress = await testContract.wethToken.callAsync(); wethTokenAddress = await testContract.wethToken().callAsync();
}); });
describe('isValidSignature()', () => { describe('isValidSignature()', () => {
it('returns success bytes', async () => { it('returns success bytes', async () => {
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381'; const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
const result = await testContract.isValidSignature.callAsync(hexRandom(), hexRandom(_.random(0, 32))); const result = await testContract
.isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32)))
.callAsync();
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE); expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
}); });
}); });
@@ -89,35 +88,35 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> { async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> {
const _opts = createWithdrawToOpts(opts); const _opts = createWithdrawToOpts(opts);
const callData = { value: new BigNumber(_opts.exchangeFillAmount) };
// Create the "from" token and exchange. // Create the "from" token and exchange.
[[_opts.fromTokenAddress]] = await txHelper.getResultAndReceiptAsync( const createFromTokenFn = testContract.createTokenAndExchange(
testContract.createTokenAndExchange,
_opts.fromTokenAddress, _opts.fromTokenAddress,
_opts.exchangeRevertReason, _opts.exchangeRevertReason,
{ value: new BigNumber(_opts.exchangeFillAmount) },
); );
[_opts.fromTokenAddress] = await createFromTokenFn.callAsync(callData);
await createFromTokenFn.awaitTransactionSuccessAsync(callData);
// Create the "to" token and exchange. // Create the "to" token and exchange.
[[_opts.toTokenAddress]] = await txHelper.getResultAndReceiptAsync( const createToTokenFn = testContract.createTokenAndExchange(
testContract.createTokenAndExchange,
_opts.toTokenAddress, _opts.toTokenAddress,
_opts.exchangeRevertReason, _opts.exchangeRevertReason,
{ value: new BigNumber(_opts.exchangeFillAmount) },
);
await testContract.setTokenRevertReason.awaitTransactionSuccessAsync(
_opts.toTokenAddress,
_opts.toTokenRevertReason,
);
await testContract.setTokenRevertReason.awaitTransactionSuccessAsync(
_opts.fromTokenAddress,
_opts.fromTokenRevertReason,
); );
[_opts.toTokenAddress] = await createToTokenFn.callAsync(callData);
await createToTokenFn.awaitTransactionSuccessAsync(callData);
await testContract
.setTokenRevertReason(_opts.toTokenAddress, _opts.toTokenRevertReason)
.awaitTransactionSuccessAsync();
await testContract
.setTokenRevertReason(_opts.fromTokenAddress, _opts.fromTokenRevertReason)
.awaitTransactionSuccessAsync();
// Set the token balance for the token we're converting from. // Set the token balance for the token we're converting from.
await testContract.setTokenBalance.awaitTransactionSuccessAsync(_opts.fromTokenAddress, { await testContract.setTokenBalance(_opts.fromTokenAddress).awaitTransactionSuccessAsync({
value: new BigNumber(_opts.fromTokenBalance), value: new BigNumber(_opts.fromTokenBalance),
}); });
// Call bridgeTransferFrom(). // Call bridgeTransferFrom().
const [result, receipt] = await txHelper.getResultAndReceiptAsync( const bridgeTransferFromFn = testContract.bridgeTransferFrom(
testContract.bridgeTransferFrom,
// The "to" token address. // The "to" token address.
_opts.toTokenAddress, _opts.toTokenAddress,
// The "from" address. // The "from" address.
@@ -127,8 +126,10 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
// The amount to transfer to "to" // The amount to transfer to "to"
new BigNumber(_opts.amount), new BigNumber(_opts.amount),
// ABI-encoded "from" token address. // ABI-encoded "from" token address.
hexLeftPad(_opts.fromTokenAddress), hexUtils.leftPad(_opts.fromTokenAddress),
); );
const result = await bridgeTransferFromFn.callAsync();
const receipt = await bridgeTransferFromFn.awaitTransactionSuccessAsync();
return { return {
opts: _opts, opts: _opts,
result, result,
@@ -138,7 +139,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
} }
async function getExchangeForTokenAsync(tokenAddress: string): Promise<string> { async function getExchangeForTokenAsync(tokenAddress: string): Promise<string> {
return testContract.getExchange.callAsync(tokenAddress); return testContract.getExchange(tokenAddress).callAsync();
} }
it('returns magic bytes on success', async () => { it('returns magic bytes on success', async () => {
@@ -147,11 +148,9 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
}); });
it('just transfers tokens to `to` if the same tokens are in play', async () => { it('just transfers tokens to `to` if the same tokens are in play', async () => {
const [[tokenAddress]] = await txHelper.getResultAndReceiptAsync( const createTokenFn = await testContract.createTokenAndExchange(constants.NULL_ADDRESS, '');
testContract.createTokenAndExchange, const [tokenAddress] = await createTokenFn.callAsync();
constants.NULL_ADDRESS, await createTokenFn.awaitTransactionSuccessAsync();
'',
);
const { opts, result, logs } = await withdrawToAsync({ const { opts, result, logs } = await withdrawToAsync({
fromTokenAddress: tokenAddress, fromTokenAddress: tokenAddress,
toTokenAddress: tokenAddress, toTokenAddress: tokenAddress,
@@ -203,14 +202,16 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
}); });
it('fails if "from" token does not exist', async () => { it('fails if "from" token does not exist', async () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync( const tx = testContract
randomAddress(), .bridgeTransferFrom(
randomAddress(), randomAddress(),
randomAddress(), randomAddress(),
getRandomInteger(1, 1e18), randomAddress(),
hexLeftPad(randomAddress()), getRandomInteger(1, 1e18),
); hexUtils.leftPad(randomAddress()),
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN'); )
.awaitTransactionSuccessAsync();
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
}); });
it('fails if the exchange fails', async () => { it('fails if the exchange fails', async () => {
@@ -218,7 +219,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
const tx = withdrawToAsync({ const tx = withdrawToAsync({
exchangeRevertReason: revertReason, exchangeRevertReason: revertReason,
}); });
return expect(tx).to.revertWith(revertReason); return expect(tx).to.eventually.be.rejectedWith(revertReason);
}); });
}); });
@@ -275,14 +276,16 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
}); });
it('fails if "from" token does not exist', async () => { it('fails if "from" token does not exist', async () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync( const tx = testContract
randomAddress(), .bridgeTransferFrom(
randomAddress(), randomAddress(),
randomAddress(), randomAddress(),
getRandomInteger(1, 1e18), randomAddress(),
hexLeftPad(wethTokenAddress), getRandomInteger(1, 1e18),
); hexUtils.leftPad(wethTokenAddress),
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN'); )
.awaitTransactionSuccessAsync();
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
}); });
it('fails if `WETH.deposit()` fails', async () => { it('fails if `WETH.deposit()` fails', async () => {
@@ -291,7 +294,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
toTokenAddress: wethTokenAddress, toTokenAddress: wethTokenAddress,
toTokenRevertReason: revertReason, toTokenRevertReason: revertReason,
}); });
return expect(tx).to.revertWith(revertReason); return expect(tx).to.eventually.be.rejectedWith(revertReason);
}); });
it('fails if the exchange fails', async () => { it('fails if the exchange fails', async () => {
@@ -300,7 +303,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
toTokenAddress: wethTokenAddress, toTokenAddress: wethTokenAddress,
exchangeRevertReason: revertReason, exchangeRevertReason: revertReason,
}); });
return expect(tx).to.revertWith(revertReason); return expect(tx).to.eventually.be.rejectedWith(revertReason);
}); });
}); });
@@ -333,14 +336,16 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
}); });
it('fails if "to" token does not exist', async () => { it('fails if "to" token does not exist', async () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync( const tx = testContract
wethTokenAddress, .bridgeTransferFrom(
randomAddress(), wethTokenAddress,
randomAddress(), randomAddress(),
getRandomInteger(1, 1e18), randomAddress(),
hexLeftPad(randomAddress()), getRandomInteger(1, 1e18),
); hexUtils.leftPad(randomAddress()),
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN'); )
.awaitTransactionSuccessAsync();
return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
}); });
it('fails if the `WETH.withdraw()` fails', async () => { it('fails if the `WETH.withdraw()` fails', async () => {
@@ -349,7 +354,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
fromTokenAddress: wethTokenAddress, fromTokenAddress: wethTokenAddress,
fromTokenRevertReason: revertReason, fromTokenRevertReason: revertReason,
}); });
return expect(tx).to.revertWith(revertReason); return expect(tx).to.eventually.be.rejectedWith(revertReason);
}); });
it('fails if the exchange fails', async () => { it('fails if the exchange fails', async () => {
@@ -358,7 +363,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
fromTokenAddress: wethTokenAddress, fromTokenAddress: wethTokenAddress,
exchangeRevertReason: revertReason, exchangeRevertReason: revertReason,
}); });
return expect(tx).to.revertWith(revertReason); return expect(tx).to.eventually.be.rejectedWith(revertReason);
}); });
}); });
}); });

View File

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

View File

@@ -0,0 +1,34 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
export * from '../test/generated-wrappers/chai_bridge';
export * from '../test/generated-wrappers/erc1155_proxy';
export * from '../test/generated-wrappers/erc20_bridge_proxy';
export * from '../test/generated-wrappers/erc20_proxy';
export * from '../test/generated-wrappers/erc721_proxy';
export * from '../test/generated-wrappers/eth2_dai_bridge';
export * from '../test/generated-wrappers/i_asset_data';
export * from '../test/generated-wrappers/i_asset_proxy';
export * from '../test/generated-wrappers/i_asset_proxy_dispatcher';
export * from '../test/generated-wrappers/i_authorizable';
export * from '../test/generated-wrappers/i_chai';
export * from '../test/generated-wrappers/i_erc20_bridge';
export * from '../test/generated-wrappers/i_eth2_dai';
export * from '../test/generated-wrappers/i_kyber_network_proxy';
export * from '../test/generated-wrappers/i_uniswap_exchange';
export * from '../test/generated-wrappers/i_uniswap_exchange_factory';
export * from '../test/generated-wrappers/kyber_bridge';
export * from '../test/generated-wrappers/mixin_asset_proxy_dispatcher';
export * from '../test/generated-wrappers/mixin_authorizable';
export * from '../test/generated-wrappers/multi_asset_proxy';
export * from '../test/generated-wrappers/ownable';
export * from '../test/generated-wrappers/static_call_proxy';
export * from '../test/generated-wrappers/test_chai_bridge';
export * from '../test/generated-wrappers/test_erc20_bridge';
export * from '../test/generated-wrappers/test_eth2_dai_bridge';
export * from '../test/generated-wrappers/test_kyber_bridge';
export * from '../test/generated-wrappers/test_static_call_target';
export * from '../test/generated-wrappers/test_uniswap_bridge';
export * from '../test/generated-wrappers/uniswap_bridge';

View File

@@ -3,6 +3,7 @@
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true }, "compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"], "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": [ "files": [
"generated-artifacts/ChaiBridge.json",
"generated-artifacts/ERC1155Proxy.json", "generated-artifacts/ERC1155Proxy.json",
"generated-artifacts/ERC20BridgeProxy.json", "generated-artifacts/ERC20BridgeProxy.json",
"generated-artifacts/ERC20Proxy.json", "generated-artifacts/ERC20Proxy.json",
@@ -10,22 +11,40 @@
"generated-artifacts/Eth2DaiBridge.json", "generated-artifacts/Eth2DaiBridge.json",
"generated-artifacts/IAssetData.json", "generated-artifacts/IAssetData.json",
"generated-artifacts/IAssetProxy.json", "generated-artifacts/IAssetProxy.json",
"generated-artifacts/IAssetProxyDispatcher.json", "generated-artifacts/KyberBridge.json",
"generated-artifacts/IAuthorizable.json",
"generated-artifacts/IERC20Bridge.json",
"generated-artifacts/IEth2Dai.json",
"generated-artifacts/IUniswapExchange.json",
"generated-artifacts/IUniswapExchangeFactory.json",
"generated-artifacts/MixinAssetProxyDispatcher.json",
"generated-artifacts/MixinAuthorizable.json",
"generated-artifacts/MultiAssetProxy.json", "generated-artifacts/MultiAssetProxy.json",
"generated-artifacts/Ownable.json",
"generated-artifacts/StaticCallProxy.json", "generated-artifacts/StaticCallProxy.json",
"generated-artifacts/TestERC20Bridge.json",
"generated-artifacts/TestEth2DaiBridge.json",
"generated-artifacts/TestStaticCallTarget.json", "generated-artifacts/TestStaticCallTarget.json",
"generated-artifacts/TestUniswapBridge.json", "generated-artifacts/UniswapBridge.json",
"generated-artifacts/UniswapBridge.json" "test/generated-artifacts/ChaiBridge.json",
"test/generated-artifacts/ERC1155Proxy.json",
"test/generated-artifacts/ERC20BridgeProxy.json",
"test/generated-artifacts/ERC20Proxy.json",
"test/generated-artifacts/ERC721Proxy.json",
"test/generated-artifacts/Eth2DaiBridge.json",
"test/generated-artifacts/IAssetData.json",
"test/generated-artifacts/IAssetProxy.json",
"test/generated-artifacts/IAssetProxyDispatcher.json",
"test/generated-artifacts/IAuthorizable.json",
"test/generated-artifacts/IChai.json",
"test/generated-artifacts/IERC20Bridge.json",
"test/generated-artifacts/IEth2Dai.json",
"test/generated-artifacts/IKyberNetworkProxy.json",
"test/generated-artifacts/IUniswapExchange.json",
"test/generated-artifacts/IUniswapExchangeFactory.json",
"test/generated-artifacts/KyberBridge.json",
"test/generated-artifacts/MixinAssetProxyDispatcher.json",
"test/generated-artifacts/MixinAuthorizable.json",
"test/generated-artifacts/MultiAssetProxy.json",
"test/generated-artifacts/Ownable.json",
"test/generated-artifacts/StaticCallProxy.json",
"test/generated-artifacts/TestChaiBridge.json",
"test/generated-artifacts/TestERC20Bridge.json",
"test/generated-artifacts/TestEth2DaiBridge.json",
"test/generated-artifacts/TestKyberBridge.json",
"test/generated-artifacts/TestStaticCallTarget.json",
"test/generated-artifacts/TestUniswapBridge.json",
"test/generated-artifacts/UniswapBridge.json"
], ],
"exclude": ["./deploy/solc/solc_bin"] "exclude": ["./deploy/solc/solc_bin"]
} }

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,107 @@
[ [
{
"timestamp": 1575931811,
"version": "3.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "3.0.0",
"changes": [
{
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
"pr": 2330
},
{
"note": "Introduced new export CoordinatorRevertErrors",
"pr": 2321
},
{
"note": "Added dependency on @0x/contracts-utils",
"pr": 2321
},
{
"note": "Add chainId to domain separator",
"pr": 1742
},
{
"note": "Inherit Exchange domain constants from `exchange-libs` to reduce code duplication",
"pr": 1742
},
{
"note": "Update domain separator",
"pr": 1742
},
{
"note": "Refactor contract to use new ITransactions interface",
"pr": 1753
},
{
"note": "Add verifyingContractIfExists arg to LibEIP712CoordinatorDomain constructor",
"pr": 1753
},
{
"note": "Remove LibZeroExTransaction contract",
"pr": 1753
},
{
"note": "Update tests for arbitrary fee tokens (ZEIP-28).",
"pr": 1819
},
{
"note": "Update for new `marketXOrders` consolidation.",
"pr": 2042
},
{
"note": "Use built in selectors instead of hard coded constants",
"pr": 2055
},
{
"note": "Compile and export all contracts, artifacts, and wrappers by default",
"pr": 2055
}
],
"timestamp": 1575296764
},
{
"version": "2.1.0-beta.4",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1575290197
},
{
"version": "2.1.0-beta.3",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1574238768
},
{
"version": "2.1.0-beta.2",
"changes": [
{
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
"pr": 2330
},
{
"note": "Introduced new export CoordinatorRevertErrors",
"pr": 2321
},
{
"note": "Added dependency on @0x/contracts-utils",
"pr": 2321
}
],
"timestamp": 1574030254
},
{ {
"version": "2.1.0-beta.1", "version": "2.1.0-beta.1",
"changes": [ "changes": [

View File

@@ -5,6 +5,40 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v3.0.1 - _December 9, 2019_
* Dependencies updated
## v3.0.0 - _December 2, 2019_
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
* Introduced new export CoordinatorRevertErrors (#2321)
* Added dependency on @0x/contracts-utils (#2321)
* Add chainId to domain separator (#1742)
* Inherit Exchange domain constants from `exchange-libs` to reduce code duplication (#1742)
* Update domain separator (#1742)
* Refactor contract to use new ITransactions interface (#1753)
* Add verifyingContractIfExists arg to LibEIP712CoordinatorDomain constructor (#1753)
* Remove LibZeroExTransaction contract (#1753)
* Update tests for arbitrary fee tokens (ZEIP-28). (#1819)
* Update for new `marketXOrders` consolidation. (#2042)
* Use built in selectors instead of hard coded constants (#2055)
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
## v2.1.0-beta.4 - _December 2, 2019_
* Dependencies updated
## v2.1.0-beta.3 - _November 20, 2019_
* Dependencies updated
## v2.1.0-beta.2 - _November 17, 2019_
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
* Introduced new export CoordinatorRevertErrors (#2321)
* Added dependency on @0x/contracts-utils (#2321)
## v2.1.0-beta.1 - _November 7, 2019_ ## v2.1.0-beta.1 - _November 7, 2019_
* Dependencies updated * Dependencies updated

View File

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

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-coordinator", "name": "@0x/contracts-coordinator",
"version": "2.1.0-beta.1", "version": "3.0.1",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -12,7 +12,7 @@
"scripts": { "scripts": {
"build": "yarn pre_build && tsc -b", "build": "yarn pre_build && tsc -b",
"build:ci": "yarn build", "build:ci": "yarn build",
"pre_build": "run-s compile contracts:gen generate_contract_wrappers", "pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
"test": "yarn run_mocha", "test": "yarn run_mocha",
"rebuild_and_test": "run-s build test", "rebuild_and_test": "run-s build test",
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
@@ -21,21 +21,25 @@
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit", "run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile": "sol-compiler", "compile": "sol-compiler",
"watch": "sol-compiler -w", "watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers", "clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers", "generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", "lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", "fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text", "coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html", "coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html", "profiler:report:html": "istanbul report html && open coverage/index.html",
"coverage:report:lcov": "istanbul report lcov", "coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test", "test:circleci": "yarn test",
"contracts:gen": "contracts-gen", "contracts:gen": "contracts-gen generate",
"contracts:copy": "contracts-gen copy",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol", "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
"compile:truffle": "truffle compile" "compile:truffle": "truffle compile",
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
}, },
"config": { "config": {
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry|ICoordinatorApprovalVerifier|ICoordinatorCore|ICoordinatorRegistryCore|ICoordinatorSignatureValidator|LibConstants|LibCoordinatorApproval|LibCoordinatorRichErrors|LibEIP712CoordinatorDomain|MixinCoordinatorApprovalVerifier|MixinCoordinatorCore|MixinCoordinatorRegistryCore|MixinSignatureValidator).json", "publicInterfaceContracts": "Coordinator,CoordinatorRegistry,LibCoordinatorApproval,LibCoordinatorRichErrors,LibEIP712CoordinatorDomain,LibConstants",
"abis": "./test/generated-artifacts/@(Coordinator|CoordinatorRegistry|ICoordinatorApprovalVerifier|ICoordinatorCore|ICoordinatorRegistryCore|ICoordinatorSignatureValidator|LibConstants|LibCoordinatorApproval|LibCoordinatorRichErrors|LibEIP712CoordinatorDomain|MixinCoordinatorApprovalVerifier|MixinCoordinatorCore|MixinCoordinatorRegistryCore|MixinSignatureValidator).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
}, },
"repository": { "repository": {
@@ -48,17 +52,19 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
"devDependencies": { "devDependencies": {
"@0x/abi-gen": "^4.4.0-beta.1", "@0x/abi-gen": "^5.0.1",
"@0x/contracts-asset-proxy": "^2.3.0-beta.1", "@0x/contracts-asset-proxy": "^3.0.1",
"@0x/contracts-dev-utils": "^0.1.0-beta.1", "@0x/contracts-dev-utils": "^1.0.1",
"@0x/contracts-erc20": "^2.3.0-beta.1", "@0x/contracts-erc20": "^3.0.1",
"@0x/contracts-exchange": "^2.2.0-beta.1", "@0x/contracts-exchange": "^3.0.1",
"@0x/contracts-gen": "^1.1.0-beta.1", "@0x/contracts-gen": "^2.0.1",
"@0x/contracts-test-utils": "^3.2.0-beta.1", "@0x/contracts-test-utils": "^5.0.0",
"@0x/dev-utils": "^2.4.0-beta.1", "@0x/dev-utils": "^3.0.1",
"@0x/order-utils": "^8.5.0-beta.1", "@0x/order-utils": "^10.0.0",
"@0x/sol-compiler": "^3.2.0-beta.1", "@0x/sol-compiler": "^4.0.1",
"@0x/tslint-config": "^3.1.0-beta.1", "@0x/ts-doc-gen": "^0.0.22",
"@0x/tslint-config": "^4.0.0",
"@0x/web3-wrapper": "^7.0.1",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7", "@types/mocha": "^5.2.7",
"@types/node": "*", "@types/node": "*",
@@ -74,16 +80,20 @@
"solhint": "^1.4.1", "solhint": "^1.4.1",
"truffle": "^5.0.32", "truffle": "^5.0.32",
"tslint": "5.11.0", "tslint": "5.11.0",
"typedoc": "^0.15.0",
"typescript": "3.0.1" "typescript": "3.0.1"
}, },
"dependencies": { "dependencies": {
"@0x/base-contract": "^5.5.0-beta.1", "@0x/assert": "^3.0.1",
"@0x/types": "^2.5.0-beta.1", "@0x/base-contract": "^6.0.1",
"@0x/typescript-typings": "^4.4.0-beta.1", "@0x/contract-addresses": "^4.0.0",
"@0x/utils": "^4.6.0-beta.1", "@0x/contracts-utils": "^4.0.1",
"@0x/web3-wrapper": "^6.1.0-beta.1", "@0x/json-schemas": "^5.0.1",
"ethereum-types": "^2.2.0-beta.1", "@0x/types": "^3.1.0",
"ethereumjs-util": "^5.1.1" "@0x/typescript-typings": "^5.0.0",
"@0x/utils": "^5.1.0",
"ethereum-types": "^3.0.0",
"http-status-codes": "^1.3.2"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View File

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

View File

@@ -7,31 +7,15 @@ import { ContractArtifact } from 'ethereum-types';
import * as Coordinator from '../generated-artifacts/Coordinator.json'; import * as Coordinator from '../generated-artifacts/Coordinator.json';
import * as CoordinatorRegistry from '../generated-artifacts/CoordinatorRegistry.json'; import * as CoordinatorRegistry from '../generated-artifacts/CoordinatorRegistry.json';
import * as ICoordinatorApprovalVerifier from '../generated-artifacts/ICoordinatorApprovalVerifier.json';
import * as ICoordinatorCore from '../generated-artifacts/ICoordinatorCore.json';
import * as ICoordinatorRegistryCore from '../generated-artifacts/ICoordinatorRegistryCore.json';
import * as ICoordinatorSignatureValidator from '../generated-artifacts/ICoordinatorSignatureValidator.json';
import * as LibConstants from '../generated-artifacts/LibConstants.json'; import * as LibConstants from '../generated-artifacts/LibConstants.json';
import * as LibCoordinatorApproval from '../generated-artifacts/LibCoordinatorApproval.json'; import * as LibCoordinatorApproval from '../generated-artifacts/LibCoordinatorApproval.json';
import * as LibCoordinatorRichErrors from '../generated-artifacts/LibCoordinatorRichErrors.json'; import * as LibCoordinatorRichErrors from '../generated-artifacts/LibCoordinatorRichErrors.json';
import * as LibEIP712CoordinatorDomain from '../generated-artifacts/LibEIP712CoordinatorDomain.json'; import * as LibEIP712CoordinatorDomain from '../generated-artifacts/LibEIP712CoordinatorDomain.json';
import * as MixinCoordinatorApprovalVerifier from '../generated-artifacts/MixinCoordinatorApprovalVerifier.json';
import * as MixinCoordinatorCore from '../generated-artifacts/MixinCoordinatorCore.json';
import * as MixinCoordinatorRegistryCore from '../generated-artifacts/MixinCoordinatorRegistryCore.json';
import * as MixinSignatureValidator from '../generated-artifacts/MixinSignatureValidator.json';
export const artifacts = { export const artifacts = {
Coordinator: Coordinator as ContractArtifact, Coordinator: Coordinator as ContractArtifact,
MixinCoordinatorApprovalVerifier: MixinCoordinatorApprovalVerifier as ContractArtifact, CoordinatorRegistry: CoordinatorRegistry as ContractArtifact,
MixinCoordinatorCore: MixinCoordinatorCore as ContractArtifact,
MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
ICoordinatorApprovalVerifier: ICoordinatorApprovalVerifier as ContractArtifact,
ICoordinatorCore: ICoordinatorCore as ContractArtifact,
ICoordinatorSignatureValidator: ICoordinatorSignatureValidator as ContractArtifact,
LibConstants: LibConstants as ContractArtifact,
LibCoordinatorApproval: LibCoordinatorApproval as ContractArtifact, LibCoordinatorApproval: LibCoordinatorApproval as ContractArtifact,
LibCoordinatorRichErrors: LibCoordinatorRichErrors as ContractArtifact, LibCoordinatorRichErrors: LibCoordinatorRichErrors as ContractArtifact,
LibEIP712CoordinatorDomain: LibEIP712CoordinatorDomain as ContractArtifact, LibEIP712CoordinatorDomain: LibEIP712CoordinatorDomain as ContractArtifact,
CoordinatorRegistry: CoordinatorRegistry as ContractArtifact, LibConstants: LibConstants as ContractArtifact,
MixinCoordinatorRegistryCore: MixinCoordinatorRegistryCore as ContractArtifact,
ICoordinatorRegistryCore: ICoordinatorRegistryCore as ContractArtifact,
}; };

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

View File

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

View File

@@ -0,0 +1,29 @@
import { eip712Utils } from '@0x/order-utils';
import { SignedZeroExTransaction } from '@0x/types';
import { hexUtils, signTypedDataUtils } from '@0x/utils';
export const hashUtils = {
async getApprovalHashBufferAsync(
transaction: SignedZeroExTransaction,
verifyingContract: string,
txOrigin: string,
): Promise<Buffer> {
const typedData = await eip712Utils.createCoordinatorApprovalTypedDataAsync(
transaction,
verifyingContract,
txOrigin,
);
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
return hashBuffer;
},
async getApprovalHashHexAsync(
transaction: SignedZeroExTransaction,
verifyingContract: string,
txOrigin: string,
): Promise<string> {
const hashHex = hexUtils.concat(
await hashUtils.getApprovalHashBufferAsync(transaction, verifyingContract, txOrigin),
);
return hashHex;
},
};

View File

@@ -1,3 +1,66 @@
export * from './artifacts'; export { artifacts } from './artifacts';
export * from './wrappers'; export {
export * from '../test/utils'; CoordinatorContract,
CoordinatorRegistryContract,
LibConstantsContract,
LibCoordinatorApprovalContract,
LibCoordinatorRichErrorsContract,
LibEIP712CoordinatorDomainContract,
} from './wrappers';
export { CoordinatorRevertErrors } from '@0x/utils';
export { CoordinatorServerCancellationResponse } from './client/index';
export { ApprovalFactory } from './approval_factory';
export { SignedCoordinatorApproval } from './types';
export {
Order,
SignedOrder,
SignatureType,
SignedZeroExTransaction,
EIP712DomainWithDefaultSchema,
ZeroExTransaction,
} from '@0x/types';
export { AwaitTransactionSuccessOpts, SendTransactionOpts } from '@0x/base-contract';
export {
ContractArtifact,
ContractChains,
CompilerOpts,
StandardContractOutput,
CompilerSettings,
ContractChainData,
ContractAbi,
DevdocOutput,
EvmOutput,
CompilerSettingsMetadata,
OptimizerSettings,
OutputField,
ParamDescription,
EvmBytecodeOutput,
AbiDefinition,
FunctionAbi,
EventAbi,
RevertErrorAbi,
EventParameter,
DataItem,
MethodAbi,
ConstructorAbi,
FallbackAbi,
ConstructorStateMutability,
TupleDataItem,
StateMutability,
SupportedProvider,
TxData,
TxDataPayable,
Web3JsProvider,
GanacheProvider,
EIP1193Provider,
ZeroExProvider,
EIP1193Event,
JSONRPCRequestPayload,
JSONRPCErrorCallback,
Web3JsV1Provider,
Web3JsV2Provider,
Web3JsV3Provider,
JSONRPCResponsePayload,
JSONRPCResponseError,
} from 'ethereum-types';
export { CoordinatorClient, CoordinatorServerErrorMsg } from './client/index';

View File

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

View File

@@ -5,15 +5,7 @@
*/ */
export * from '../generated-wrappers/coordinator'; export * from '../generated-wrappers/coordinator';
export * from '../generated-wrappers/coordinator_registry'; export * from '../generated-wrappers/coordinator_registry';
export * from '../generated-wrappers/i_coordinator_approval_verifier';
export * from '../generated-wrappers/i_coordinator_core';
export * from '../generated-wrappers/i_coordinator_registry_core';
export * from '../generated-wrappers/i_coordinator_signature_validator';
export * from '../generated-wrappers/lib_constants'; export * from '../generated-wrappers/lib_constants';
export * from '../generated-wrappers/lib_coordinator_approval'; export * from '../generated-wrappers/lib_coordinator_approval';
export * from '../generated-wrappers/lib_coordinator_rich_errors'; export * from '../generated-wrappers/lib_coordinator_rich_errors';
export * from '../generated-wrappers/lib_e_i_p712_coordinator_domain'; export * from '../generated-wrappers/lib_e_i_p712_coordinator_domain';
export * from '../generated-wrappers/mixin_coordinator_approval_verifier';
export * from '../generated-wrappers/mixin_coordinator_core';
export * from '../generated-wrappers/mixin_coordinator_registry_core';
export * from '../generated-wrappers/mixin_signature_validator';

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 { blockchainTests, expect, verifyEvents } from '@0x/contracts-test-utils';
import { artifacts, CoordinatorRegistryContract, CoordinatorRegistryCoordinatorEndpointSetEventArgs } from '../src'; import { artifacts } from './artifacts';
import { CoordinatorRegistryContract, CoordinatorRegistryCoordinatorEndpointSetEventArgs } from './wrappers';
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
blockchainTests.resets('Coordinator Registry tests', env => { blockchainTests.resets('Coordinator Registry tests', env => {
@@ -23,43 +25,42 @@ blockchainTests.resets('Coordinator Registry tests', env => {
}); });
describe('core', () => { describe('core', () => {
it('Should successfully set a Coordinator endpoint', async () => { it('Should successfully set a Coordinator endpoint', async () => {
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, { await coordinatorRegistry.setCoordinatorEndpoint(coordinatorEndpoint).awaitTransactionSuccessAsync({
from: coordinatorOperator, from: coordinatorOperator,
}); });
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync( const recordedCoordinatorEndpoint = await coordinatorRegistry
coordinatorOperator, .getCoordinatorEndpoint(coordinatorOperator)
); .callAsync();
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint); expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
}); });
it('Should successfully unset a Coordinator endpoint', async () => { it('Should successfully unset a Coordinator endpoint', async () => {
// set Coordinator endpoint // set Coordinator endpoint
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, { await coordinatorRegistry.setCoordinatorEndpoint(coordinatorEndpoint).awaitTransactionSuccessAsync({
from: coordinatorOperator, from: coordinatorOperator,
}); });
let recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync( let recordedCoordinatorEndpoint = await coordinatorRegistry
coordinatorOperator, .getCoordinatorEndpoint(coordinatorOperator)
); .callAsync();
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint); expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
// unset Coordinator endpoint // unset Coordinator endpoint
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(nilCoordinatorEndpoint, { await coordinatorRegistry.setCoordinatorEndpoint(nilCoordinatorEndpoint).awaitTransactionSuccessAsync({
from: coordinatorOperator, from: coordinatorOperator,
}); });
recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync( recordedCoordinatorEndpoint = await coordinatorRegistry
coordinatorOperator, .getCoordinatorEndpoint(coordinatorOperator)
); .callAsync();
expect(recordedCoordinatorEndpoint).to.be.equal(nilCoordinatorEndpoint); expect(recordedCoordinatorEndpoint).to.be.equal(nilCoordinatorEndpoint);
}); });
it('Should emit an event when setting Coordinator endpoint', async () => { it('Should emit an event when setting Coordinator endpoint', async () => {
// set Coordinator endpoint // set Coordinator endpoint
const txReceipt = await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync( const txReceipt = await coordinatorRegistry
coordinatorEndpoint, .setCoordinatorEndpoint(coordinatorEndpoint)
{ .awaitTransactionSuccessAsync({
from: coordinatorOperator, from: coordinatorOperator,
}, });
); const recordedCoordinatorEndpoint = await coordinatorRegistry
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync( .getCoordinatorEndpoint(coordinatorOperator)
coordinatorOperator, .callAsync();
);
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint); expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
// validate event // validate event
const expectedEvent: CoordinatorRegistryCoordinatorEndpointSetEventArgs = { const expectedEvent: CoordinatorRegistryCoordinatorEndpointSetEventArgs = {

View File

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

View File

@@ -1,18 +1,22 @@
import { constants as exchangeConstants, exchangeDataEncoder, ExchangeFunctionName } from '@0x/contracts-exchange'; import { exchangeDataEncoder } from '@0x/contracts-exchange';
import { import {
blockchainTests, blockchainTests,
constants, constants,
ExchangeFunctionName,
expect, expect,
hexConcat,
hexSlice,
randomAddress, randomAddress,
TransactionFactory, TransactionFactory,
transactionHashUtils,
} from '@0x/contracts-test-utils'; } from '@0x/contracts-test-utils';
import { CoordinatorRevertErrors, transactionHashUtils } from '@0x/order-utils'; import { LibBytesRevertErrors } from '@0x/contracts-utils';
import { SignatureType, SignedOrder } from '@0x/types'; import { SignatureType, SignedOrder } from '@0x/types';
import { BigNumber, LibBytesRevertErrors } from '@0x/utils'; import { BigNumber, CoordinatorRevertErrors, hexUtils } from '@0x/utils';
import { ApprovalFactory, artifacts, CoordinatorContract } from '../src'; import { ApprovalFactory } from '../src/approval_factory';
import { artifacts } from './artifacts';
import { CoordinatorContract } from './wrappers';
blockchainTests.resets('Mixins tests', env => { blockchainTests.resets('Mixins tests', env => {
let chainId: number; let chainId: number;
@@ -70,25 +74,25 @@ blockchainTests.resets('Mixins tests', env => {
const data = constants.NULL_BYTES; const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EthSign); const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EthSign);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature); const signerAddress = await mixins.getSignerAddress(transactionHash, transaction.signature).callAsync();
expect(transaction.signerAddress).to.eq(signerAddress); expect(transaction.signerAddress).to.eq(signerAddress);
}); });
it('should return the correct address using the EIP712 signature type', async () => { it('should return the correct address using the EIP712 signature type', async () => {
const data = constants.NULL_BYTES; const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EIP712); const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EIP712);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature); const signerAddress = await mixins.getSignerAddress(transactionHash, transaction.signature).callAsync();
expect(transaction.signerAddress).to.eq(signerAddress); expect(transaction.signerAddress).to.eq(signerAddress);
}); });
it('should revert with with the Illegal signature type', async () => { it('should revert with with the Illegal signature type', async () => {
const data = constants.NULL_BYTES; const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat( transaction.signature = hexUtils.concat(
hexSlice(transaction.signature, 0, transaction.signature.length - 1), hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1),
SignatureType.Illegal, SignatureType.Illegal,
); );
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith( expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith(
new CoordinatorRevertErrors.SignatureError( new CoordinatorRevertErrors.SignatureError(
CoordinatorRevertErrors.SignatureErrorCodes.Illegal, CoordinatorRevertErrors.SignatureErrorCodes.Illegal,
transactionHash, transactionHash,
@@ -99,9 +103,9 @@ blockchainTests.resets('Mixins tests', env => {
it('should revert with with the Invalid signature type', async () => { it('should revert with with the Invalid signature type', async () => {
const data = constants.NULL_BYTES; const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat(SignatureType.Invalid); transaction.signature = hexUtils.concat(SignatureType.Invalid);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith( expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith(
new CoordinatorRevertErrors.SignatureError( new CoordinatorRevertErrors.SignatureError(
CoordinatorRevertErrors.SignatureErrorCodes.Invalid, CoordinatorRevertErrors.SignatureErrorCodes.Invalid,
transactionHash, transactionHash,
@@ -112,12 +116,12 @@ blockchainTests.resets('Mixins tests', env => {
it('should revert with with a signature type that equals `NSignatureTypes`', async () => { it('should revert with with a signature type that equals `NSignatureTypes`', async () => {
const data = constants.NULL_BYTES; const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat( transaction.signature = hexUtils.concat(
hexSlice(transaction.signature, 0, transaction.signature.length - 1), hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1),
SignatureType.NSignatureTypes, SignatureType.NSignatureTypes,
); );
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith( expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith(
new CoordinatorRevertErrors.SignatureError( new CoordinatorRevertErrors.SignatureError(
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported, CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
transactionHash, transactionHash,
@@ -128,12 +132,12 @@ blockchainTests.resets('Mixins tests', env => {
it("should revert with with a signature type that isn't supported", async () => { it("should revert with with a signature type that isn't supported", async () => {
const data = constants.NULL_BYTES; const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat( transaction.signature = hexUtils.concat(
hexSlice(transaction.signature, 0, transaction.signature.length - 1), hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1),
SignatureType.Wallet, SignatureType.Wallet,
); );
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith( expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith(
new CoordinatorRevertErrors.SignatureError( new CoordinatorRevertErrors.SignatureError(
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported, CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
transactionHash, transactionHash,
@@ -144,11 +148,11 @@ blockchainTests.resets('Mixins tests', env => {
}); });
describe('decodeOrdersFromFillData', () => { describe('decodeOrdersFromFillData', () => {
for (const fnName of exchangeConstants.SINGLE_FILL_FN_NAMES) { for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => { it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data); const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
const decodedSignedOrders = decodedOrders.map(order => ({ const decodedSignedOrders = decodedOrders.map(order => ({
...order, ...order,
signature: constants.NULL_BYTES, signature: constants.NULL_BYTES,
@@ -158,11 +162,11 @@ blockchainTests.resets('Mixins tests', env => {
expect(orders).to.deep.eq(decodedSignedOrders); expect(orders).to.deep.eq(decodedSignedOrders);
}); });
} }
for (const fnName of exchangeConstants.BATCH_FILL_FN_NAMES) { for (const fnName of constants.BATCH_FILL_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => { it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data); const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
const decodedSignedOrders = decodedOrders.map(order => ({ const decodedSignedOrders = decodedOrders.map(order => ({
...order, ...order,
signature: constants.NULL_BYTES, signature: constants.NULL_BYTES,
@@ -172,11 +176,11 @@ blockchainTests.resets('Mixins tests', env => {
expect(orders).to.deep.eq(decodedSignedOrders); expect(orders).to.deep.eq(decodedSignedOrders);
}); });
} }
for (const fnName of exchangeConstants.MARKET_FILL_FN_NAMES) { for (const fnName of constants.MARKET_FILL_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => { it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data); const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
const decodedSignedOrders = decodedOrders.map(order => ({ const decodedSignedOrders = decodedOrders.map(order => ({
...order, ...order,
signature: constants.NULL_BYTES, signature: constants.NULL_BYTES,
@@ -186,11 +190,11 @@ blockchainTests.resets('Mixins tests', env => {
expect(orders).to.deep.eq(decodedSignedOrders); expect(orders).to.deep.eq(decodedSignedOrders);
}); });
} }
for (const fnName of exchangeConstants.MATCH_ORDER_FN_NAMES) { for (const fnName of constants.MATCH_ORDER_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => { it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data); const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
const decodedSignedOrders = decodedOrders.map(order => ({ const decodedSignedOrders = decodedOrders.map(order => ({
...order, ...order,
signature: constants.NULL_BYTES, signature: constants.NULL_BYTES,
@@ -200,18 +204,18 @@ blockchainTests.resets('Mixins tests', env => {
expect(orders).to.deep.eq(decodedSignedOrders); expect(orders).to.deep.eq(decodedSignedOrders);
}); });
} }
for (const fnName of exchangeConstants.CANCEL_ORDER_FN_NAMES) { for (const fnName of constants.CANCEL_ORDER_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => { it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data); const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
const emptyArray: any[] = []; const emptyArray: any[] = [];
expect(emptyArray).to.deep.eq(decodedOrders); expect(emptyArray).to.deep.eq(decodedOrders);
}); });
} }
it('should decode an empty array for invalid data', async () => { it('should decode an empty array for invalid data', async () => {
const data = '0x0123456789'; const data = '0x0123456789';
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data); const decodedOrders = await mixins.decodeOrdersFromFillData(data).callAsync();
const emptyArray: any[] = []; const emptyArray: any[] = [];
expect(emptyArray).to.deep.eq(decodedOrders); expect(emptyArray).to.deep.eq(decodedOrders);
}); });
@@ -222,24 +226,22 @@ blockchainTests.resets('Mixins tests', env => {
new BigNumber(3), // the length of data new BigNumber(3), // the length of data
new BigNumber(4), new BigNumber(4),
); );
return expect(mixins.decodeOrdersFromFillData.callAsync(data)).to.revertWith(expectedError); return expect(mixins.decodeOrdersFromFillData(data).callAsync()).to.revertWith(expectedError);
}); });
}); });
describe('Single order approvals', () => { describe('Single order approvals', () => {
for (const fnName of exchangeConstants.SINGLE_FILL_FN_NAMES) { for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1]`, async () => { it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval.signature,
transaction.signature, ])
[approval.signature], .callAsync({ from: transactionSignerAddress });
{ from: transactionSignerAddress },
);
}); });
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1]`, async () => { it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1]`, async () => {
const order = { const order = {
@@ -249,73 +251,59 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [order]; const orders = [order];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval.signature,
transaction.signature, ])
[approval.signature], .callAsync({ from: transactionSignerAddress });
{ from: transactionSignerAddress },
);
}); });
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => { it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
approvalSignerAddress1, .callAsync({
transaction.signature,
[],
{
from: approvalSignerAddress1, from: approvalSignerAddress1,
}, });
);
}); });
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1]`, async () => { it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [
approvalSignerAddress1, approval.signature,
transaction.signature, ])
[approval.signature], .callAsync({ from: approvalSignerAddress1 });
{ from: approvalSignerAddress1 },
);
}); });
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => { it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
approvalSignerAddress1, .callAsync({
transaction.signature,
[],
{
from: approvalSignerAddress1, from: approvalSignerAddress1,
}, });
);
}); });
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid]`, async () => { it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid]`, async () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const signature = hexConcat( const signature = hexUtils.concat(
hexSlice(approval.signature, 0, 2), hexUtils.slice(approval.signature, 0, 2),
'0xFFFFFFFF', '0xFFFFFFFF',
hexSlice(approval.signature, 6), hexUtils.slice(approval.signature, 6),
);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[signature],
{ from: transactionSignerAddress },
); );
const tx = mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
signature,
])
.callAsync({ from: transactionSignerAddress });
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith( expect(tx).to.revertWith(
@@ -326,37 +314,33 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync( const tx = mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval.signature,
transaction.signature, ])
[approval.signature], .callAsync({ from: approvalSignerAddress2 });
{ from: approvalSignerAddress2 },
);
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress)); expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
}); });
} }
}); });
describe('Batch order approvals', () => { describe('Batch order approvals', () => {
for (const fnName of [ for (const fnName of [
...exchangeConstants.BATCH_FILL_FN_NAMES, ...constants.BATCH_FILL_FN_NAMES,
...exchangeConstants.MARKET_FILL_FN_NAMES, ...constants.MARKET_FILL_FN_NAMES,
...exchangeConstants.MATCH_ORDER_FN_NAMES, ...constants.MATCH_ORDER_FN_NAMES,
]) { ]) {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => { it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval.signature,
transaction.signature, ])
[approval.signature], .callAsync({ from: transactionSignerAddress });
{ from: transactionSignerAddress },
);
}); });
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => { it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder, defaultOrder].map(order => ({ const orders = [defaultOrder, defaultOrder].map(order => ({
@@ -365,14 +349,12 @@ blockchainTests.resets('Mixins tests', env => {
})); }));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval.signature,
transaction.signature, ])
[approval.signature], .callAsync({ from: transactionSignerAddress });
{ from: transactionSignerAddress },
);
}); });
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => { it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
const orders = [defaultOrder, defaultOrder].map(order => ({ const orders = [defaultOrder, defaultOrder].map(order => ({
@@ -381,79 +363,62 @@ blockchainTests.resets('Mixins tests', env => {
})); }));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
transactionSignerAddress, .callAsync({ from: transactionSignerAddress });
transaction.signature,
[],
{ from: transactionSignerAddress },
);
}); });
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => { it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, senderAddress: constants.NULL_ADDRESS }]; const orders = [defaultOrder, { ...defaultOrder, senderAddress: constants.NULL_ADDRESS }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval.signature,
transaction.signature, ])
[approval.signature], .callAsync({ from: transactionSignerAddress });
{ from: transactionSignerAddress },
);
}); });
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2]`, async () => { it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress); const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval1.signature,
transaction.signature, approval2.signature,
[approval1.signature, approval2.signature], ])
{ from: transactionSignerAddress }, .callAsync({ from: transactionSignerAddress });
);
}); });
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => { it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [])
approvalSignerAddress1, .callAsync({ from: approvalSignerAddress1 });
transaction.signature,
[],
{ from: approvalSignerAddress1 },
);
}); });
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2]`, async () => { it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress); const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync( const tx = mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval2.signature,
transaction.signature, ])
[approval2.signature], .callAsync({ from: approvalSignerAddress1 });
{ from: approvalSignerAddress1 },
);
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress)); expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
}); });
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[]`, async () => { it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[]`, async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const tx = mixins.assertValidCoordinatorApprovals.callAsync( const tx = mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
transactionSignerAddress, .callAsync({ from: transactionSignerAddress });
transaction.signature,
[],
{ from: transactionSignerAddress },
);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith( expect(tx).to.revertWith(
@@ -464,19 +429,17 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const signature = hexConcat( const signature = hexUtils.concat(
hexSlice(approval.signature, 0, 2), hexUtils.slice(approval.signature, 0, 2),
'0xFFFFFFFF', '0xFFFFFFFF',
hexSlice(approval.signature, 6), hexUtils.slice(approval.signature, 6),
);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[signature],
{ from: transactionSignerAddress },
); );
const tx = mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
signature,
])
.callAsync({ from: transactionSignerAddress });
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith( expect(tx).to.revertWith(
@@ -487,20 +450,19 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress); const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
const approvalSignature2 = hexConcat( const approvalSignature2 = hexUtils.concat(
hexSlice(approval2.signature, 0, 2), hexUtils.slice(approval2.signature, 0, 2),
'0xFFFFFFFF', '0xFFFFFFFF',
hexSlice(approval2.signature, 6), hexUtils.slice(approval2.signature, 6),
);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approval1.signature, approvalSignature2],
{ from: transactionSignerAddress },
); );
const tx = mixins
.assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
approval1.signature,
approvalSignature2,
])
.callAsync({ from: transactionSignerAddress });
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith( expect(tx).to.revertWith(
@@ -511,19 +473,17 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress); const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress);
const approvalSignature2 = hexConcat( const approvalSignature2 = hexUtils.concat(
hexSlice(approval2.signature, 0, 2), hexUtils.slice(approval2.signature, 0, 2),
'0xFFFFFFFF', '0xFFFFFFFF',
hexSlice(approval2.signature, 6), hexUtils.slice(approval2.signature, 6),
);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[approvalSignature2],
{ from: approvalSignerAddress1 },
); );
const tx = mixins
.assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [
approvalSignature2,
])
.callAsync({ from: approvalSignerAddress1 });
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith( expect(tx).to.revertWith(
@@ -534,15 +494,13 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress); const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync( const tx = mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [
transactionSignerAddress, approval1.signature,
transaction.signature, ])
[approval1.signature], .callAsync({ from: approvalSignerAddress2 });
{ from: approvalSignerAddress2 },
);
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress)); expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
}); });
} }
@@ -552,36 +510,24 @@ blockchainTests.resets('Mixins tests', env => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
transactionSignerAddress, .callAsync({ from: transactionSignerAddress });
transaction.signature,
[],
{ from: transactionSignerAddress },
);
}); });
it('should allow the tx signer to call `batchCancelOrders` without approval', async () => { it('should allow the tx signer to call `batchCancelOrders` without approval', async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.BatchCancelOrders, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.BatchCancelOrders, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
transactionSignerAddress, .callAsync({ from: transactionSignerAddress });
transaction.signature,
[],
{ from: transactionSignerAddress },
);
}); });
it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => { it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo); const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo);
const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins
transaction, .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [])
transactionSignerAddress, .callAsync({ from: transactionSignerAddress });
transaction.signature,
[],
{ from: transactionSignerAddress },
);
}); });
}); });
}); });

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": [ "files": [
"generated-artifacts/Coordinator.json", "generated-artifacts/Coordinator.json",
"generated-artifacts/CoordinatorRegistry.json", "generated-artifacts/CoordinatorRegistry.json",
"generated-artifacts/ICoordinatorApprovalVerifier.json",
"generated-artifacts/ICoordinatorCore.json",
"generated-artifacts/ICoordinatorRegistryCore.json",
"generated-artifacts/ICoordinatorSignatureValidator.json",
"generated-artifacts/LibConstants.json", "generated-artifacts/LibConstants.json",
"generated-artifacts/LibCoordinatorApproval.json", "generated-artifacts/LibCoordinatorApproval.json",
"generated-artifacts/LibCoordinatorRichErrors.json", "generated-artifacts/LibCoordinatorRichErrors.json",
"generated-artifacts/LibEIP712CoordinatorDomain.json", "generated-artifacts/LibEIP712CoordinatorDomain.json",
"generated-artifacts/MixinCoordinatorApprovalVerifier.json", "test/generated-artifacts/Coordinator.json",
"generated-artifacts/MixinCoordinatorCore.json", "test/generated-artifacts/CoordinatorRegistry.json",
"generated-artifacts/MixinCoordinatorRegistryCore.json", "test/generated-artifacts/ICoordinatorApprovalVerifier.json",
"generated-artifacts/MixinSignatureValidator.json" "test/generated-artifacts/ICoordinatorCore.json",
"test/generated-artifacts/ICoordinatorRegistryCore.json",
"test/generated-artifacts/ICoordinatorSignatureValidator.json",
"test/generated-artifacts/LibConstants.json",
"test/generated-artifacts/LibCoordinatorApproval.json",
"test/generated-artifacts/LibCoordinatorRichErrors.json",
"test/generated-artifacts/LibEIP712CoordinatorDomain.json",
"test/generated-artifacts/MixinCoordinatorApprovalVerifier.json",
"test/generated-artifacts/MixinCoordinatorCore.json",
"test/generated-artifacts/MixinCoordinatorRegistryCore.json",
"test/generated-artifacts/MixinSignatureValidator.json"
], ],
"exclude": ["./deploy/solc/solc_bin"] "exclude": ["./deploy/solc/solc_bin"]
} }

View File

@@ -3,5 +3,5 @@
"compilerOptions": { "compilerOptions": {
"outDir": "lib" "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,91 @@
[ [
{
"timestamp": 1575931811,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.0.0",
"changes": [
{
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
"pr": 2330
},
{
"note": "Add new method getOrderHash() to DevUtils contract",
"pr": 2321
},
{
"note": "Add new method getTransactionHash() to DevUtils contract",
"pr": 2321
},
{
"note": "Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData",
"pr": 2034
},
{
"note": "Add `revertIfInvalidAssetData` in LibAssetData",
"pr": 2034
},
{
"note": "Use built in selectors instead of hard coded constants",
"pr": 2055
},
{
"note": "Compile and export all contracts, artifacts, and wrappers by default",
"pr": 2055
},
{
"note": "Add `marketBuy/SellOrdersNoThrow` and `marketBuy/SellOrdersFillOrKill` to `LibTransactionDecoder`.",
"pr": 2075
},
{
"note": "`run_mocha` package script runs with `UNLIMITED_CONTRACT_SIZE=true` environment variable.",
"pr": 2075
}
],
"timestamp": 1575296764
},
{
"version": "0.1.0-beta.4",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1575290197
},
{
"version": "0.1.0-beta.3",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1574238768
},
{
"version": "0.1.0-beta.2",
"changes": [
{
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
"pr": 2330
},
{
"note": "Add new method getOrderHash() to DevUtils contract",
"pr": 2321
},
{
"note": "Add new method getTransactionHash() to DevUtils contract",
"pr": 2321
}
],
"timestamp": 1574030254
},
{ {
"version": "0.1.0-beta.1", "version": "0.1.0-beta.1",
"changes": [ "changes": [

View File

@@ -5,6 +5,36 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.1 - _December 9, 2019_
* Dependencies updated
## v1.0.0 - _December 2, 2019_
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
* Add new method getOrderHash() to DevUtils contract (#2321)
* Add new method getTransactionHash() to DevUtils contract (#2321)
* Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData (#2034)
* Add `revertIfInvalidAssetData` in LibAssetData (#2034)
* Use built in selectors instead of hard coded constants (#2055)
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
* Add `marketBuy/SellOrdersNoThrow` and `marketBuy/SellOrdersFillOrKill` to `LibTransactionDecoder`. (#2075)
* `run_mocha` package script runs with `UNLIMITED_CONTRACT_SIZE=true` environment variable. (#2075)
## v0.1.0-beta.4 - _December 2, 2019_
* Dependencies updated
## v0.1.0-beta.3 - _November 20, 2019_
* Dependencies updated
## v0.1.0-beta.2 - _November 17, 2019_
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
* Add new method getOrderHash() to DevUtils contract (#2321)
* Add new method getTransactionHash() to DevUtils contract (#2321)
## v0.1.0-beta.1 - _November 7, 2019_ ## v0.1.0-beta.1 - _November 7, 2019_
* Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData (#2034) * Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData (#2034)

View File

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

View File

@@ -19,6 +19,11 @@
pragma solidity ^0.5.5; pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol";
import "@0x/contracts-utils/contracts/src/LibEIP712.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "./OrderValidationUtils.sol"; import "./OrderValidationUtils.sol";
import "./OrderTransferSimulationUtils.sol"; import "./OrderTransferSimulationUtils.sol";
import "./LibTransactionDecoder.sol"; import "./LibTransactionDecoder.sol";
@@ -29,6 +34,7 @@ import "./EthBalanceChecker.sol";
contract DevUtils is contract DevUtils is
OrderValidationUtils, OrderValidationUtils,
LibTransactionDecoder, LibTransactionDecoder,
LibEIP712ExchangeDomain,
EthBalanceChecker, EthBalanceChecker,
OrderTransferSimulationUtils OrderTransferSimulationUtils
{ {
@@ -36,5 +42,32 @@ contract DevUtils is
public public
OrderValidationUtils(_exchange) OrderValidationUtils(_exchange)
OrderTransferSimulationUtils(_exchange) OrderTransferSimulationUtils(_exchange)
LibEIP712ExchangeDomain(uint256(0), address(0)) // null args because because we only use constants
{} {}
function getOrderHash(LibOrder.Order memory order, uint256 chainId, address exchange)
public
pure
returns (bytes32 orderHash)
{
return LibOrder.getTypedDataHash(
order,
LibEIP712.hashEIP712Domain(_EIP712_EXCHANGE_DOMAIN_NAME, _EIP712_EXCHANGE_DOMAIN_VERSION, chainId, exchange)
);
}
function getTransactionHash(
LibZeroExTransaction.ZeroExTransaction memory transaction,
uint256 chainId,
address exchange
)
public
pure
returns (bytes32 transactionHash)
{
return LibZeroExTransaction.getTypedDataHash(
transaction,
LibEIP712.hashEIP712Domain(_EIP712_EXCHANGE_DOMAIN_NAME, _EIP712_EXCHANGE_DOMAIN_VERSION, chainId, exchange)
);
}
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-dev-utils", "name": "@0x/contracts-dev-utils",
"version": "0.1.0-beta.1", "version": "1.0.1",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -8,22 +8,27 @@
"main": "lib/src/index.js", "main": "lib/src/index.js",
"scripts": { "scripts": {
"build": "yarn pre_build && tsc -b", "build": "yarn pre_build && tsc -b",
"test": "echo !!! Run tests in @0x/contracts-tests instead !!!", "test": "yarn assert_deployable && echo !!! Tests are run via @0x/contracts-tests !!!",
"assert_deployable": "node -e \"const bytecodeLen = (require('./generated-artifacts/DevUtils.json').compilerOutput.evm.bytecode.object.length-2)/2; assert(bytecodeLen<=0x6000,'DevUtils contract is too big to deploy, per EIP-170. '+bytecodeLen+'>'+0x6000)\"",
"build:ci": "yarn build", "build:ci": "yarn build",
"pre_build": "run-s compile quantify_bytecode contracts:gen generate_contract_wrappers", "pre_build": "run-s compile quantify_bytecode contracts:gen generate_contract_wrappers contracts:copy",
"compile": "sol-compiler", "compile": "sol-compiler",
"watch": "sol-compiler -w", "watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers", "clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers", "generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", "lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", "fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"contracts:gen": "contracts-gen", "contracts:gen": "contracts-gen generate",
"contracts:copy": "contracts-gen copy",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol", "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
"quantify_bytecode": "echo EVM bytecode object lengths:;for i in ./generated-artifacts/*.json; do node -e \"console.log('$i\t' + (require('$i').compilerOutput.evm.bytecode.object.length - 2) / 2)\"; done", "quantify_bytecode": "echo EVM bytecode object lengths:;for i in ./test/generated-artifacts/*.json; do node -e \"console.log('$i\t' + (require('$i').compilerOutput.evm.bytecode.object.length - 2) / 2)\"; done",
"compile:truffle": "truffle compile" "compile:truffle": "truffle compile",
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
}, },
"config": { "config": {
"abis": "./generated-artifacts/@(DevUtils|EthBalanceChecker|LibAssetData|LibTransactionDecoder|OrderTransferSimulationUtils|OrderValidationUtils).json", "publicInterfaceContracts": "DevUtils,LibAssetData,LibTransactionDecoder",
"abis": "./test/generated-artifacts/@(DevUtils|EthBalanceChecker|LibAssetData|LibTransactionDecoder|OrderTransferSimulationUtils|OrderValidationUtils).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
}, },
"repository": { "repository": {
@@ -36,28 +41,25 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md",
"devDependencies": { "devDependencies": {
"@0x/abi-gen": "^4.4.0-beta.1", "@0x/abi-gen": "^5.0.1",
"@0x/contracts-gen": "^1.1.0-beta.1", "@0x/assert": "^3.0.1",
"@0x/sol-compiler": "^3.2.0-beta.1", "@0x/contracts-gen": "^2.0.1",
"@0x/tslint-config": "^3.1.0-beta.1", "@0x/sol-compiler": "^4.0.1",
"@0x/ts-doc-gen": "^0.0.22",
"@0x/tslint-config": "^4.0.0",
"@types/node": "*", "@types/node": "*",
"ethereum-types": "^3.0.0",
"ethers": "~4.0.4",
"npm-run-all": "^4.1.2", "npm-run-all": "^4.1.2",
"shx": "^0.2.2", "shx": "^0.2.2",
"solhint": "^1.4.1", "solhint": "^1.4.1",
"truffle": "^5.0.32", "truffle": "^5.0.32",
"tslint": "5.11.0", "tslint": "5.11.0",
"typedoc": "^0.15.0",
"typescript": "3.0.1" "typescript": "3.0.1"
}, },
"dependencies": { "dependencies": {
"@0x/assert": "^2.2.0-beta.1", "@0x/base-contract": "^6.0.1"
"@0x/base-contract": "^5.5.0-beta.1",
"@0x/contract-addresses": "^3.3.0-beta.2",
"@0x/json-schemas": "^4.1.0-beta.1",
"@0x/types": "^2.5.0-beta.1",
"@0x/utils": "^4.6.0-beta.1",
"@0x/web3-wrapper": "^6.1.0-beta.1",
"ethereum-types": "^2.2.0-beta.1",
"ethers": "~4.0.4"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View File

@@ -6,16 +6,10 @@
import { ContractArtifact } from 'ethereum-types'; import { ContractArtifact } from 'ethereum-types';
import * as DevUtils from '../generated-artifacts/DevUtils.json'; import * as DevUtils from '../generated-artifacts/DevUtils.json';
import * as EthBalanceChecker from '../generated-artifacts/EthBalanceChecker.json';
import * as LibAssetData from '../generated-artifacts/LibAssetData.json'; import * as LibAssetData from '../generated-artifacts/LibAssetData.json';
import * as LibTransactionDecoder from '../generated-artifacts/LibTransactionDecoder.json'; import * as LibTransactionDecoder from '../generated-artifacts/LibTransactionDecoder.json';
import * as OrderTransferSimulationUtils from '../generated-artifacts/OrderTransferSimulationUtils.json';
import * as OrderValidationUtils from '../generated-artifacts/OrderValidationUtils.json';
export const artifacts = { export const artifacts = {
DevUtils: DevUtils as ContractArtifact, DevUtils: DevUtils as ContractArtifact,
EthBalanceChecker: EthBalanceChecker as ContractArtifact,
LibAssetData: LibAssetData as ContractArtifact, LibAssetData: LibAssetData as ContractArtifact,
LibTransactionDecoder: LibTransactionDecoder as ContractArtifact, LibTransactionDecoder: LibTransactionDecoder as ContractArtifact,
OrderTransferSimulationUtils: OrderTransferSimulationUtils as ContractArtifact,
OrderValidationUtils: OrderValidationUtils as ContractArtifact,
}; };

View File

@@ -1,2 +1,30 @@
export * from './artifacts'; export { artifacts } from './artifacts';
export * from './wrappers'; export { DevUtilsContract, LibAssetDataContract, LibTransactionDecoderContract } from './wrappers';
export {
ContractArtifact,
ContractChains,
CompilerOpts,
StandardContractOutput,
CompilerSettings,
ContractChainData,
ContractAbi,
DevdocOutput,
EvmOutput,
CompilerSettingsMetadata,
OptimizerSettings,
OutputField,
ParamDescription,
EvmBytecodeOutput,
AbiDefinition,
FunctionAbi,
EventAbi,
RevertErrorAbi,
EventParameter,
DataItem,
MethodAbi,
ConstructorAbi,
FallbackAbi,
ConstructorStateMutability,
TupleDataItem,
StateMutability,
} from 'ethereum-types';

View File

@@ -4,8 +4,5 @@
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
*/ */
export * from '../generated-wrappers/dev_utils'; export * from '../generated-wrappers/dev_utils';
export * from '../generated-wrappers/eth_balance_checker';
export * from '../generated-wrappers/lib_asset_data'; export * from '../generated-wrappers/lib_asset_data';
export * from '../generated-wrappers/lib_transaction_decoder'; export * from '../generated-wrappers/lib_transaction_decoder';
export * from '../generated-wrappers/order_transfer_simulation_utils';
export * from '../generated-wrappers/order_validation_utils';

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/**/*"], "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": [ "files": [
"generated-artifacts/DevUtils.json", "generated-artifacts/DevUtils.json",
"generated-artifacts/EthBalanceChecker.json",
"generated-artifacts/LibAssetData.json", "generated-artifacts/LibAssetData.json",
"generated-artifacts/LibTransactionDecoder.json", "generated-artifacts/LibTransactionDecoder.json",
"generated-artifacts/OrderTransferSimulationUtils.json", "test/generated-artifacts/DevUtils.json",
"generated-artifacts/OrderValidationUtils.json" "test/generated-artifacts/EthBalanceChecker.json",
"test/generated-artifacts/LibAssetData.json",
"test/generated-artifacts/LibTransactionDecoder.json",
"test/generated-artifacts/OrderTransferSimulationUtils.json",
"test/generated-artifacts/OrderValidationUtils.json"
], ],
"exclude": ["./deploy/solc/solc_bin"] "exclude": ["./deploy/solc/solc_bin"]
} }

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,59 @@
[ [
{
"timestamp": 1575931811,
"version": "2.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.0.0",
"changes": [
{
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
"pr": 2330
},
{
"note": "Add `mintKnownFungibleTokensAsync()`, `isNonFungibleItemAsync()`, `isFungibleItemAsync()`, `getOwnerOfAsync()`, `getBalanceAsync()` to `Erc1155Wrapper`.",
"pr": 1819
},
{
"note": "Replaced `SafeMath` with `LibSafeMath`",
"pr": 2254
}
],
"timestamp": 1575296764
},
{
"version": "1.2.0-beta.4",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1575290197
},
{
"version": "1.2.0-beta.3",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1574238768
},
{
"version": "1.2.0-beta.2",
"changes": [
{
"note": "Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils",
"pr": 2330
}
],
"timestamp": 1574030254
},
{ {
"version": "1.2.0-beta.1", "version": "1.2.0-beta.1",
"changes": [ "changes": [

View File

@@ -5,6 +5,28 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v2.0.1 - _December 9, 2019_
* Dependencies updated
## v2.0.0 - _December 2, 2019_
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
* Add `mintKnownFungibleTokensAsync()`, `isNonFungibleItemAsync()`, `isFungibleItemAsync()`, `getOwnerOfAsync()`, `getBalanceAsync()` to `Erc1155Wrapper`. (#1819)
* Replaced `SafeMath` with `LibSafeMath` (#2254)
## v1.2.0-beta.4 - _December 2, 2019_
* Dependencies updated
## v1.2.0-beta.3 - _November 20, 2019_
* Dependencies updated
## v1.2.0-beta.2 - _November 17, 2019_
* Drastically reduced bundle size by adding .npmignore, only exporting specific artifacts/wrappers/utils (#2330)
## v1.2.0-beta.1 - _November 7, 2019_ ## v1.2.0-beta.1 - _November 7, 2019_
* Dependencies updated * Dependencies updated

View File

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

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-erc1155", "name": "@0x/contracts-erc1155",
"version": "1.2.0-beta.1", "version": "2.0.1",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@@ -12,7 +12,7 @@
"scripts": { "scripts": {
"build": "yarn pre_build && tsc -b", "build": "yarn pre_build && tsc -b",
"build:ci": "yarn build", "build:ci": "yarn build",
"pre_build": "run-s compile contracts:gen generate_contract_wrappers", "pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
"test": "yarn run_mocha", "test": "yarn run_mocha",
"rebuild_and_test": "run-s build test", "rebuild_and_test": "run-s build test",
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
@@ -21,21 +21,25 @@
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit", "run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile": "sol-compiler", "compile": "sol-compiler",
"watch": "sol-compiler -w", "watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers", "clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers", "generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", "lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", "fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text", "coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html", "coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html", "profiler:report:html": "istanbul report html && open coverage/index.html",
"coverage:report:lcov": "istanbul report lcov", "coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test", "test:circleci": "yarn test",
"contracts:gen": "contracts-gen", "contracts:gen": "contracts-gen generate",
"contracts:copy": "contracts-gen copy",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol", "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
"compile:truffle": "truffle compile" "compile:truffle": "truffle compile",
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
}, },
"config": { "config": {
"abis": "./generated-artifacts/@(DummyERC1155Receiver|ERC1155|ERC1155Mintable|IERC1155|IERC1155Mintable|IERC1155Receiver|MixinNonFungibleToken).json", "publicInterfaceContracts": "ERC1155,ERC1155Mintable,IERC1155Receiver,DummyERC1155Receiver",
"abis": "./test/generated-artifacts/@(DummyERC1155Receiver|ERC1155|ERC1155Mintable|IERC1155|IERC1155Mintable|IERC1155Receiver|MixinNonFungibleToken).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
}, },
"repository": { "repository": {
@@ -48,11 +52,15 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
"devDependencies": { "devDependencies": {
"@0x/abi-gen": "^4.4.0-beta.1", "@0x/abi-gen": "^5.0.1",
"@0x/contracts-gen": "^1.1.0-beta.1", "@0x/contracts-gen": "^2.0.1",
"@0x/dev-utils": "^2.4.0-beta.1", "@0x/contracts-utils": "^4.0.1",
"@0x/sol-compiler": "^3.2.0-beta.1", "@0x/dev-utils": "^3.0.1",
"@0x/tslint-config": "^3.1.0-beta.1", "@0x/sol-compiler": "^4.0.1",
"@0x/ts-doc-gen": "^0.0.22",
"@0x/tslint-config": "^4.0.0",
"@0x/types": "^3.1.0",
"@0x/typescript-typings": "^5.0.0",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7", "@types/mocha": "^5.2.7",
"@types/node": "*", "@types/node": "*",
@@ -60,6 +68,7 @@
"chai-as-promised": "^7.1.0", "chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0", "chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1", "dirty-chai": "^2.0.1",
"ethereum-types": "^3.0.0",
"make-promises-safe": "^1.1.0", "make-promises-safe": "^1.1.0",
"mocha": "^6.2.0", "mocha": "^6.2.0",
"npm-run-all": "^4.1.2", "npm-run-all": "^4.1.2",
@@ -67,17 +76,14 @@
"solhint": "^1.4.1", "solhint": "^1.4.1",
"truffle": "^5.0.32", "truffle": "^5.0.32",
"tslint": "5.11.0", "tslint": "5.11.0",
"typedoc": "^0.15.0",
"typescript": "3.0.1" "typescript": "3.0.1"
}, },
"dependencies": { "dependencies": {
"@0x/base-contract": "^5.5.0-beta.1", "@0x/base-contract": "^6.0.1",
"@0x/contracts-test-utils": "^3.2.0-beta.1", "@0x/contracts-test-utils": "^5.0.0",
"@0x/contracts-utils": "^3.3.0-beta.1", "@0x/utils": "^5.1.0",
"@0x/types": "^2.5.0-beta.1", "@0x/web3-wrapper": "^7.0.1",
"@0x/typescript-typings": "^4.4.0-beta.1",
"@0x/utils": "^4.6.0-beta.1",
"@0x/web3-wrapper": "^6.1.0-beta.1",
"ethereum-types": "^2.2.0-beta.1",
"lodash": "^4.17.11" "lodash": "^4.17.11"
}, },
"publishConfig": { "publishConfig": {

View File

@@ -8,16 +8,10 @@ import { ContractArtifact } from 'ethereum-types';
import * as DummyERC1155Receiver from '../generated-artifacts/DummyERC1155Receiver.json'; import * as DummyERC1155Receiver from '../generated-artifacts/DummyERC1155Receiver.json';
import * as ERC1155 from '../generated-artifacts/ERC1155.json'; import * as ERC1155 from '../generated-artifacts/ERC1155.json';
import * as ERC1155Mintable from '../generated-artifacts/ERC1155Mintable.json'; import * as ERC1155Mintable from '../generated-artifacts/ERC1155Mintable.json';
import * as IERC1155 from '../generated-artifacts/IERC1155.json';
import * as IERC1155Mintable from '../generated-artifacts/IERC1155Mintable.json';
import * as IERC1155Receiver from '../generated-artifacts/IERC1155Receiver.json'; import * as IERC1155Receiver from '../generated-artifacts/IERC1155Receiver.json';
import * as MixinNonFungibleToken from '../generated-artifacts/MixinNonFungibleToken.json';
export const artifacts = { export const artifacts = {
ERC1155: ERC1155 as ContractArtifact, ERC1155: ERC1155 as ContractArtifact,
ERC1155Mintable: ERC1155Mintable as ContractArtifact, ERC1155Mintable: ERC1155Mintable as ContractArtifact,
MixinNonFungibleToken: MixinNonFungibleToken as ContractArtifact,
IERC1155: IERC1155 as ContractArtifact,
IERC1155Mintable: IERC1155Mintable as ContractArtifact,
IERC1155Receiver: IERC1155Receiver as ContractArtifact, IERC1155Receiver: IERC1155Receiver as ContractArtifact,
DummyERC1155Receiver: DummyERC1155Receiver as ContractArtifact, DummyERC1155Receiver: DummyERC1155Receiver as ContractArtifact,
}; };

View File

@@ -1,31 +1,22 @@
import { LogDecoder } from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import * as chai from 'chai';
import { LogWithDecodedArgs, Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { LogWithDecodedArgs, Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { artifacts, ERC1155MintableContract, ERC1155TransferSingleEventArgs } from '../../src'; import { ERC1155MintableContract, ERC1155TransferSingleEventArgs } from './wrappers';
const expect = chai.expect;
export class Erc1155Wrapper { export class Erc1155Wrapper {
private readonly _erc1155Contract: ERC1155MintableContract; private readonly _erc1155Contract: ERC1155MintableContract;
private readonly _web3Wrapper: Web3Wrapper;
private readonly _contractOwner: string; private readonly _contractOwner: string;
private readonly _logDecoder: LogDecoder;
constructor(contractInstance: ERC1155MintableContract, provider: Provider, contractOwner: string) { constructor(contractInstance: ERC1155MintableContract, provider: Provider, contractOwner: string) {
this._erc1155Contract = contractInstance; this._erc1155Contract = contractInstance;
this._web3Wrapper = new Web3Wrapper(provider);
this._contractOwner = contractOwner; this._contractOwner = contractOwner;
this._logDecoder = new LogDecoder(this._web3Wrapper, artifacts);
} }
public getContract(): ERC1155MintableContract { public getContract(): ERC1155MintableContract {
return this._erc1155Contract; return this._erc1155Contract;
} }
public async getBalancesAsync(owners: string[], tokens: BigNumber[]): Promise<BigNumber[]> { public async getBalancesAsync(owners: string[], tokens: BigNumber[]): Promise<BigNumber[]> {
const balances = await this._erc1155Contract.balanceOfBatch.callAsync(owners, tokens); const balances = await this._erc1155Contract.balanceOfBatch(owners, tokens).callAsync();
return balances; return balances;
} }
public async safeTransferFromAsync( public async safeTransferFromAsync(
@@ -38,11 +29,11 @@ export class Erc1155Wrapper {
): Promise<TransactionReceiptWithDecodedLogs> { ): Promise<TransactionReceiptWithDecodedLogs> {
const spender = delegatedSpender === undefined ? from : delegatedSpender; const spender = delegatedSpender === undefined ? from : delegatedSpender;
const callbackDataHex = callbackData === undefined ? '0x' : callbackData; const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync( const tx = await this._erc1155Contract
await this._erc1155Contract.safeTransferFrom.sendTransactionAsync(from, to, token, value, callbackDataHex, { .safeTransferFrom(from, to, token, value, callbackDataHex)
.awaitTransactionSuccessAsync({
from: spender, from: spender,
}), });
);
return tx; return tx;
} }
public async safeBatchTransferFromAsync( public async safeBatchTransferFromAsync(
@@ -55,16 +46,9 @@ export class Erc1155Wrapper {
): Promise<TransactionReceiptWithDecodedLogs> { ): Promise<TransactionReceiptWithDecodedLogs> {
const spender = delegatedSpender === undefined ? from : delegatedSpender; const spender = delegatedSpender === undefined ? from : delegatedSpender;
const callbackDataHex = callbackData === undefined ? '0x' : callbackData; const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync( const tx = await this._erc1155Contract
await this._erc1155Contract.safeBatchTransferFrom.sendTransactionAsync( .safeBatchTransferFrom(from, to, tokens, values, callbackDataHex)
from, .awaitTransactionSuccessAsync({ from: spender });
to,
tokens,
values,
callbackDataHex,
{ from: spender },
),
);
return tx; return tx;
} }
public async mintFungibleTokensAsync( public async mintFungibleTokensAsync(
@@ -73,11 +57,9 @@ export class Erc1155Wrapper {
): Promise<BigNumber> { ): Promise<BigNumber> {
const tokenUri = 'dummyFungibleToken'; const tokenUri = 'dummyFungibleToken';
const tokenIsNonFungible = false; const tokenIsNonFungible = false;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync( const tx = await this._erc1155Contract.create(tokenUri, tokenIsNonFungible).awaitTransactionSuccessAsync({
await this._erc1155Contract.create.sendTransactionAsync(tokenUri, tokenIsNonFungible, { from: this._contractOwner,
from: this._contractOwner, });
}),
);
// tslint:disable-next-line no-unnecessary-type-assertion // tslint:disable-next-line no-unnecessary-type-assertion
const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>; const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>;
const tokenId = createFungibleTokenLog.args.id; const tokenId = createFungibleTokenLog.args.id;
@@ -95,25 +77,20 @@ export class Erc1155Wrapper {
tokenAmountsAsArray.push(tokenAmounts); tokenAmountsAsArray.push(tokenAmounts);
}); });
} }
await this._erc1155Contract.mintFungible.awaitTransactionSuccessAsync( await this._erc1155Contract
tokenId, .mintFungible(tokenId, beneficiaries, tokenAmountsAsArray)
beneficiaries, .awaitTransactionSuccessAsync({ from: this._contractOwner });
tokenAmountsAsArray,
{ from: this._contractOwner },
);
} }
public async mintNonFungibleTokensAsync(beneficiaries: string[]): Promise<[BigNumber, BigNumber[]]> { public async mintNonFungibleTokensAsync(beneficiaries: string[]): Promise<[BigNumber, BigNumber[]]> {
const tokenUri = 'dummyNonFungibleToken'; const tokenUri = 'dummyNonFungibleToken';
const tokenIsNonFungible = true; const tokenIsNonFungible = true;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync( const tx = await this._erc1155Contract.create(tokenUri, tokenIsNonFungible).awaitTransactionSuccessAsync({
await this._erc1155Contract.create.sendTransactionAsync(tokenUri, tokenIsNonFungible, { from: this._contractOwner,
from: this._contractOwner, });
}),
);
// tslint:disable-next-line no-unnecessary-type-assertion // tslint:disable-next-line no-unnecessary-type-assertion
const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>; const createFungibleTokenLog = tx.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>;
const token = createFungibleTokenLog.args.id; const token = createFungibleTokenLog.args.id;
await this._erc1155Contract.mintNonFungible.awaitTransactionSuccessAsync(token, beneficiaries, { await this._erc1155Contract.mintNonFungible(token, beneficiaries).awaitTransactionSuccessAsync({
from: this._contractOwner, from: this._contractOwner,
}); });
const encodedNftIds: BigNumber[] = []; const encodedNftIds: BigNumber[] = [];
@@ -131,15 +108,13 @@ export class Erc1155Wrapper {
beneficiary: string, beneficiary: string,
isApproved: boolean, isApproved: boolean,
): Promise<TransactionReceiptWithDecodedLogs> { ): Promise<TransactionReceiptWithDecodedLogs> {
const tx = await this._logDecoder.getTxWithDecodedLogsAsync( const tx = await this._erc1155Contract.setApprovalForAll(beneficiary, isApproved).awaitTransactionSuccessAsync({
await this._erc1155Contract.setApprovalForAll.sendTransactionAsync(beneficiary, isApproved, { from: owner,
from: owner, });
}),
);
return tx; return tx;
} }
public async isApprovedForAllAsync(owner: string, beneficiary: string): Promise<boolean> { public async isApprovedForAllAsync(owner: string, beneficiary: string): Promise<boolean> {
const isApprovedForAll = await this._erc1155Contract.isApprovedForAll.callAsync(owner, beneficiary); const isApprovedForAll = await this._erc1155Contract.isApprovedForAll(owner, beneficiary).callAsync();
return isApprovedForAll; return isApprovedForAll;
} }
public async assertBalancesAsync( public async assertBalancesAsync(
@@ -157,22 +132,24 @@ export class Erc1155Wrapper {
}); });
const balances = await this.getBalancesAsync(ownersExtended, tokensExtended); const balances = await this.getBalancesAsync(ownersExtended, tokensExtended);
_.each(balances, (balance: BigNumber, i: number) => { _.each(balances, (balance: BigNumber, i: number) => {
expect(balance, `${ownersExtended[i]}${tokensExtended[i]}`).to.be.bignumber.equal(expectedBalances[i]); if (!balance.isEqualTo(expectedBalances[i])) {
throw new Error(`${ownersExtended[i]}${tokensExtended[i]} balance not equal ${expectedBalances[i]}`);
}
}); });
} }
public async isNonFungibleItemAsync(tokenId: BigNumber): Promise<boolean> { public async isNonFungibleItemAsync(tokenId: BigNumber): Promise<boolean> {
return this._erc1155Contract.isNonFungibleItem.callAsync(tokenId); return this._erc1155Contract.isNonFungibleItem(tokenId).callAsync();
} }
public async isFungibleItemAsync(tokenId: BigNumber): Promise<boolean> { public async isFungibleItemAsync(tokenId: BigNumber): Promise<boolean> {
return !(await this.isNonFungibleItemAsync(tokenId)); return !(await this.isNonFungibleItemAsync(tokenId));
} }
public async getOwnerOfAsync(tokenId: BigNumber): Promise<string> { public async getOwnerOfAsync(tokenId: BigNumber): Promise<string> {
return this._erc1155Contract.ownerOf.callAsync(tokenId); return this._erc1155Contract.ownerOf(tokenId).callAsync();
} }
/** /**
* @dev Get the balance of an ERC1155 token for a given owner and token ID. * @dev Get the balance of an ERC1155 token for a given owner and token ID.
*/ */
public async getBalanceAsync(ownerAddress: string, tokenId: BigNumber): Promise<BigNumber> { public async getBalanceAsync(ownerAddress: string, tokenId: BigNumber): Promise<BigNumber> {
return this._erc1155Contract.balanceOf.callAsync(ownerAddress, tokenId); return this._erc1155Contract.balanceOf(ownerAddress, tokenId).callAsync();
} }
} }

View File

@@ -1,3 +1,45 @@
export * from './wrappers'; export {
export * from './artifacts'; DummyERC1155ReceiverContract,
export { Erc1155Wrapper } from '../test/utils/erc1155_wrapper'; ERC1155Contract,
ERC1155MintableContract,
IERC1155ReceiverContract,
DummyERC1155ReceiverBatchTokenReceivedEventArgs,
ERC1155TransferSingleEventArgs,
} from './wrappers';
export { artifacts } from './artifacts';
export { Erc1155Wrapper } from './erc1155_wrapper';
export {
Provider,
TransactionReceiptWithDecodedLogs,
JSONRPCRequestPayload,
JSONRPCResponsePayload,
JSONRPCResponseError,
JSONRPCErrorCallback,
TransactionReceiptStatus,
ContractArtifact,
ContractChains,
CompilerOpts,
StandardContractOutput,
CompilerSettings,
ContractChainData,
ContractAbi,
DevdocOutput,
EvmOutput,
CompilerSettingsMetadata,
OptimizerSettings,
OutputField,
ParamDescription,
EvmBytecodeOutput,
AbiDefinition,
FunctionAbi,
EventAbi,
RevertErrorAbi,
EventParameter,
DataItem,
MethodAbi,
ConstructorAbi,
FallbackAbi,
ConstructorStateMutability,
TupleDataItem,
StateMutability,
} from 'ethereum-types';

View File

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

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

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/DummyERC1155Receiver.json",
"generated-artifacts/ERC1155.json", "generated-artifacts/ERC1155.json",
"generated-artifacts/ERC1155Mintable.json", "generated-artifacts/ERC1155Mintable.json",
"generated-artifacts/IERC1155.json",
"generated-artifacts/IERC1155Mintable.json",
"generated-artifacts/IERC1155Receiver.json", "generated-artifacts/IERC1155Receiver.json",
"generated-artifacts/MixinNonFungibleToken.json" "test/generated-artifacts/DummyERC1155Receiver.json",
"test/generated-artifacts/ERC1155.json",
"test/generated-artifacts/ERC1155Mintable.json",
"test/generated-artifacts/IERC1155.json",
"test/generated-artifacts/IERC1155Mintable.json",
"test/generated-artifacts/IERC1155Receiver.json",
"test/generated-artifacts/MixinNonFungibleToken.json"
], ],
"exclude": ["./deploy/solc/solc_bin"] "exclude": ["./deploy/solc/solc_bin"]
} }

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,39 @@
[
{
"timestamp": 1575931811,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.0.0",
"changes": [
{
"note": "Created package.",
"pr": 2344
}
],
"timestamp": 1575296764
},
{
"version": "1.0.0-beta.2",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1575290197
},
{
"version": "1.0.0-beta.1",
"changes": [
{
"note": "Created package.",
"pr": 2344
}
]
}
]

View File

@@ -0,0 +1,22 @@
<!--
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
Edit the package's CHANGELOG.json file only.
-->
CHANGELOG
## v1.0.1 - _December 9, 2019_
* Dependencies updated
## v1.0.0 - _December 2, 2019_
* Created package. (#2344)
## v1.0.0-beta.2 - _December 2, 2019_
* Dependencies updated
## v1.0.0-beta.1 - _Invalid date_
* Created package. (#2344)

View File

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

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