Compare commits

...

581 Commits

Author SHA1 Message Date
Fabio Berger
e853555165 Publish
- 0x.js@6.0.10
 - @0x/abi-gen@2.1.0
 - @0x/abi-gen-templates@2.2.1
 - @0x/abi-gen-wrappers@5.0.0
 - @0x/assert@2.1.0
 - @0x/asset-buyer@6.1.6
 - @0x/asset-swapper@0.0.2
 - @0x/base-contract@5.1.1
 - @0x/connect@5.0.11
 - @0x/contract-addresses@3.0.0
 - @0x/contract-artifacts@2.0.1
 - @0x/contract-wrappers@9.1.5
 - @0x/contracts-gen@1.0.10
 - @0x/dev-tools-pages@0.0.28
 - @0x/dev-utils@2.2.4
 - ethereum-types@2.1.3
 - @0x/fill-scenarios@3.0.11
 - @0x/instant@1.0.25
 - @0x/json-schemas@3.0.11
 - @0x/metacoin@0.0.52
 - @0x/migrations@4.1.7
 - @0x/monorepo-scripts@1.0.33
 - @0x/order-utils@8.2.0
 - @0x/order-watcher@4.0.12
 - @0x/python-contract-wrappers@1.0.1
 - @0x/react-docs@2.0.13
 - @0x/react-shared@2.0.13
 - @0x/sol-compiler@3.1.9
 - @0x/sol-coverage@3.0.6
 - @0x/sol-doc@2.0.13
 - @0x/sol-profiler@3.1.8
 - @0x/sol-resolver@2.0.8
 - @0x/sol-trace@2.0.14
 - @0x/sol-tracing-utils@6.0.13
 - @0x/sra-spec@2.0.11
 - @0x/subproviders@4.1.1
 - @0x/testnet-faucets@1.0.81
 - @0x/types@2.4.0
 - @0x/typescript-typings@4.2.3
 - @0x/utils@4.4.0
 - @0x/web3-wrapper@6.0.7
 - @0x/website@0.0.84
 - @0x/contracts-asset-proxy@2.2.0
 - @0x/contracts-coordinator@2.0.5
 - @0x/contracts-dev-utils@0.0.2
 - @0x/contracts-erc1155@1.1.7
 - @0x/contracts-erc20@2.2.6
 - @0x/contracts-erc721@2.1.7
 - @0x/contracts-exchange@2.1.6
 - @0x/contracts-exchange-forwarder@3.0.4
 - @0x/contracts-exchange-libs@3.0.0
 - @0x/contracts-extensions@4.0.0
 - @0x/contracts-multisig@3.1.6
 - @0x/contracts-test-utils@3.1.8
 - @0x/contracts-utils@3.1.7
2019-07-13 01:33:08 -07:00
Fabio Berger
2ce09d73ac Updated CHANGELOGS 2019-07-13 01:32:53 -07:00
Fabio B
14f48a5f4f Merge pull request #1952 from 0xProject/fix/redeployed-2.0-mainnet
Redeployed 2.0 Mainnet
2019-07-13 09:45:59 +02:00
Jacob Evans
8da4e4a830 Redployed 2.0 Mainnet 2019-07-13 16:57:13 +10:00
Xianny
88ae8311c8 Copy dutch auction asset data utils to @0x/order-utils (#1943)
* copy dutch auction assetdata utils to @0x/order-utils

* encode/decode dutch auction asset data using order-utils
2019-07-12 17:27:06 -07:00
David Sun
eabf6a466a Fix abi-gen-wrappers dependencies 2019-07-12 16:35:50 -07:00
David Sun
989f691d06 updated dependencies versioning in package.json 2019-07-12 16:13:05 -07:00
David Sun
52a3dae7cb Merge pull request #1950 from 0xProject/feature/CFL/light-refactor
Asset-swapper method interface change
2019-07-12 15:44:41 -07:00
David Sun
8a6dfacf71 inverted erc and assetdata getSwapQuote naming 2019-07-12 15:30:25 -07:00
Xianny
19ca6c13ad Copy validation methods from ExchangeWrapper to order-utils (#1937) 2019-07-12 15:06:32 -07:00
Fabio Berger
9196f122dd Fix 0x.js version 2019-07-12 14:51:14 -07:00
David Sun
55e3d81c58 updating CHANGELOG.json + package.json 2019-07-12 14:38:19 -07:00
David Sun
80caa16718 Merge pull request #1949 from 0xProject/feature/fix-monorepo-scripts
Fix case in pre-publish write access checks
2019-07-12 14:00:35 -07:00
David Sun
ddc5aaacdb Update condition for readability
Co-Authored-By: Fabio B <me@fabioberger.com>
2019-07-12 13:39:41 -07:00
David Sun
38825865cc prettier 2019-07-12 13:32:27 -07:00
David Sun
157b2efa1d fix to not throw on new packages 2019-07-12 13:16:00 -07:00
F. Eugene Aumson
212a2d229a This one weird trick cuts contract test runtime by over 50% in CI (#1941)
* CI: Collapse each test task to a single wsrun call

* Restore test-rest to invoking wsrun many times
2019-07-12 14:11:53 -04:00
Xianny
ccb89fb26a prettify generated code for easier diffing (#1944) 2019-07-11 16:03:14 -07:00
David Sun
3a0b0c0973 Merge pull request #1939 from 0xProject/CFL
Asset-swapper 0.0.1 merge
2019-07-11 15:42:15 -07:00
David Sun
c159ed9ebb updated changelog 2019-07-11 15:16:45 -07:00
David Sun
e37dbcc273 updated package.json 2019-07-11 15:16:45 -07:00
David Sun
841e660b1f light fixes 2019-07-11 15:16:45 -07:00
David Sun
391aba5f37 updated CHANGELOG.json 2019-07-11 15:16:40 -07:00
David Sun
f5d30f4a07 Update packages/asset-buyer/src/swap_quoter.ts
Co-Authored-By: Jacob Evans <jacob@dekz.net>
2019-07-11 15:15:30 -07:00
David Sun
230cf7dfb7 Update packages/asset-buyer/src/swap_quoter.ts
Co-Authored-By: Jacob Evans <jacob@dekz.net>
2019-07-11 15:15:30 -07:00
David Sun
8734b70f83 updated README.md 2019-07-11 15:15:09 -07:00
David Sun
ff9a2b2d9a fixed docs issues 2019-07-11 15:15:09 -07:00
David Sun
a41dab2922 Commit coverage directory 2019-07-11 15:15:09 -07:00
David Sun
f4504106a1 adding back asset-buyer for legacy support 2019-07-11 15:15:09 -07:00
David Sun
1a5b8041c7 renamed to asset-swapper 2019-07-11 15:15:09 -07:00
David Sun
1e2170f8bb reverting change to abi-gen 2019-07-11 15:15:09 -07:00
David Sun
0a4a973a7f changes to types for doc generation 2019-07-11 15:15:09 -07:00
David Sun
67137cadac made get Consumer private 2019-07-11 15:15:09 -07:00
David Sun
ead4afa06b fixed linting issues 2019-07-11 15:15:09 -07:00
David Sun
e39ef95191 fixed build issues 2019-07-11 15:15:09 -07:00
David Sun
3d7585671f refactored 2019-07-11 15:15:09 -07:00
David Sun
44806106db prettier 2019-07-11 15:15:09 -07:00
David Sun
6a8197a4e8 linting issues 2019-07-11 15:15:09 -07:00
David Sun
4d4b4e0f2b lint + prettier 2019-07-11 15:15:09 -07:00
David Sun
82da33d742 light refactor 2019-07-11 15:15:09 -07:00
David Sun
1c6130a492 fixed market utils 2019-07-11 15:15:09 -07:00
David Sun
dabe5e939f fixed bugs 2019-07-11 15:15:09 -07:00
David Sun
b4ac6d3439 refactored types and market sell operation 2019-07-11 15:15:09 -07:00
David Sun
d0ea74e180 fixed linting issues 2019-07-11 15:15:08 -07:00
David Sun
a5f77f3964 prettier 2019-07-11 15:15:08 -07:00
David Sun
9401bb53e8 added testing for generating swap quotes 2019-07-11 15:15:08 -07:00
David Sun
347c6d02cf upgraded exchange sell with market sell 2019-07-11 15:15:08 -07:00
David Sun
64a0080616 add forwarder logic for market sell 2019-07-11 15:15:08 -07:00
David Sun
288a7d4cea refactored for market sell + buy 2019-07-11 15:15:08 -07:00
David Sun
1207b68f57 added market-sell logic 2019-07-11 15:15:08 -07:00
David Sun
2b82187fe0 expanded swap quoter to create market sell swap quotes 2019-07-11 15:15:08 -07:00
David Sun
3e2dbfc83c added testing to market utils for market sell 2019-07-11 15:15:08 -07:00
David Sun
6691f490bc changes to order utils 2019-07-11 15:15:08 -07:00
David Sun
a7db900e51 added types 2019-07-11 15:15:08 -07:00
David Sun
cfa2a90dae prettier 2019-07-11 15:15:08 -07:00
David Sun
feebb45e9d fixed linting issues 2019-07-11 15:15:08 -07:00
David Sun
13a2f3a330 updated to async 2019-07-11 15:15:08 -07:00
David Sun
1da8801084 switched from arrow functions 2019-07-11 15:15:08 -07:00
David Sun
7a7b17c4f3 fixed naming of utils 2019-07-11 15:15:08 -07:00
David Sun
2afb06de13 refactored forwarder to utilize utils 2019-07-11 15:15:08 -07:00
David Sun
ac771e2865 finished exchange swap quote consumer 2019-07-11 15:15:08 -07:00
David Sun
4b09204936 framework for exchange swap quote consumer 2019-07-11 15:15:08 -07:00
David Sun
e4a5518a7c refactored exchange swap quote consumer 2019-07-11 15:15:08 -07:00
David Sun
e83507ba98 added structure of exchange consumer 2019-07-11 15:15:08 -07:00
David Sun
6e5b77edb2 initial commit of exchange_swap_quote consumer 2019-07-11 15:15:08 -07:00
David Sun
98167da8fa fixing build issues
fixed build issues

prettier
2019-07-11 15:15:08 -07:00
David Sun
11d5fec59b changes on affiliate fee and other changes
bumped version to 7 and added changelog

updated package.json

revert change to package.json

trying this package.json config
2019-07-11 15:15:08 -07:00
David Sun
ed02f4ca88 switching consumer functions to async 2019-07-11 15:15:08 -07:00
David Sun
e7c612971d fixed percentage assertions 2019-07-11 15:15:08 -07:00
David Sun
242a2e21b5 updated comments
added comments to Forwarder Swap Quote Conusmer
2019-07-11 15:15:08 -07:00
David Sun
92a1e5413b change to affiliate fees 2019-07-11 15:15:08 -07:00
David Sun
e1ab9aa690 rewritten test cases for SwapQuoter
fixed testing for swap quoter + setup for consumer testing

added framework for testing consumers

added testing and updated some types
2019-07-11 15:15:08 -07:00
David Sun
222f7e6fd4 addressed reviews and light refactor
added comments to types and refactored some naming
2019-07-11 15:15:08 -07:00
David Sun
59001f827b finished forwarder consumer 2019-07-11 15:15:07 -07:00
David Sun
549bfe98f1 renamed asset-buyer + adding consumers 2019-07-11 15:15:07 -07:00
David Sun
64e3b6f5ee refactored ERC <> ERC for asset-buyer
minor update to interface
2019-07-11 15:15:07 -07:00
David Sun
2fdc0426ff temp fix for CI 2019-07-11 15:15:07 -07:00
F. Eugene Aumson
e6c70fda66 order_utils.py: pin eth-abi version (#1947)
Fixes broken builds due to new release of eth-abi.
2019-07-11 18:08:16 -04:00
Xianny
50da1354f3 Move CLI tests for abi-gen (#1930)
Closes #1925, #1926
2019-07-10 09:19:50 -07:00
Francesco Agosti
e503cacf57 Merge pull request #1916 from 0xProject/feature/website/add-theo
Adding Theo to team page
2019-07-08 13:57:36 -07:00
Fabio B
6a1e0edc78 Fix link to smart contracts 2019-07-08 21:45:40 +02:00
Xianny
048f5c2771 [Multilang] hardcode ABI into abi-gen-wrappers (#1883)
* Export artifacts and addresses from abi-gen-wrappers

* only export addresses, not artifacts

* abi-gen-wrappers no longer accept ContractAbi as constructor param

ABI is now hardcoded when wrapper is generated

* remove unused imports

* remove unused import

* changes after review

* fix method ordering

* update constructor args

* prettier

* statically enumerate ABI properties

* remove abi-gen-wrappers generated-wrappers from prettierignore

* add template for recursive components

* add `indexed` field for EventParameter

* prettier

* update known-good wrappers with ABIs and fix Python ABI loading

* remove generated-artifacts and update gitignore
2019-07-08 12:44:19 -07:00
F. Eugene Aumson
d9378e9a8f First auto-gen'd Python contract wrapper: ERC20 (#1878)
* abi-gen-wrappers: fix half-baked folder rename

* .circleci: give cache more descriptive name

* abi-gen: rename type field. tsName->langLocalName

* contract-artifacts: add devdoc to ERC20Token.json

Artifact changes crafted manually: re-generated artifacts from within
@0x/contracts-erc20, and then copied them into @0x/contract-artifacts,
but only committed the changes that added devdoc.

Modified @0x/contracts-erc20/compiler.json to include devdoc in the
hopes that next time contract-artifacts are re-generated en masse, the
devdoc output will just come along for the ride.

Compiling ERC20 TypeScript wrappers after adding devdoc to the artifacts
revealed some inconsistencies in the types.  ethereum-types'
DevdocOutput REQUIRED many fields which are not always present,
depending the devdoc contents itself.  Relaxing the requirement had some
ramifications.

* abi-gen: Python!

Lots more to come, but so far generating typed methods with some
parameter validation and with reasonable docstrings; enough to make
ERC20 work.

* existing erc20 python wrapper: re-order methods

In order to minimize the diff in the upcoming commit of the
auto-generated version.

* existing erc20 python wrapper: rename method

Rename method _erc20 to _get_contract_instance.

* existing erc20 python wrapper: rename vars

Rename method parameters to match names used in contract methods.

* existing erc20 python wrapper: correction

Contract method `allowance` previously was returning a transaction hash,
but it's a const method, so changed it to return the int that the
underlying method returns.

* contract_wrappers.py: pull in generated code

Custom setup.py command to pull in code previously generated into
../../packages/abi-gen-wrappers/src/generated-wrappers/py.

Changes to existing wrapper code reflect differences between the old,
manually-written wrapper and the new, auto-generated wrapper.

Reconfigured Circle CI to give Python build access to the output of the
TypeScript build, in order to import the generated wrappers from there.

* abi-gen: sanitize docstrings for pycodestyle lint

* abi-gen-templates.py: expose ABI from template

Use ABI given by template, not gotten by name from
zero_ex.contract_artifacts.

Also, expose ABI as a static method.

* py wrappers: contract addr to ctor, not methods

In all Python wrappers (old, manual ones; and new, generated ones), have
client pass the contract address to the wrapper's constructor, rather
than to the individual method calls.

* py wrappers: remove unused param `account_address`

* py wrappers: document use of `private_key`

* Rename file erc20_wrapper.py to erc20_token.py

To match the name of the underlying contract.

* Update CHANGELOG.json's

* git rm erc20_token.py

No need to keep it checked in.  Doing so would require manual overhead
of keeping the generated copy in sync with the generation code, which
may get overlooked and cause confusion for others.  Authoritative source
will be the published package on PyPI.

* abi-gen-templates: tweak CHANGELOG wording

Co-Authored-By: Fabio B <kandinsky454@protonmail.ch>

* Include transaction parameters in const calls too

* Doc contract_address param to gen'd wrapper ctor

* make myself a CODEOWNER of abi-gen*

* rename ids: langLocalName -> languageSpecificName

* Move Python generation to its own packages/ folder

* Stop duplicating contract artifacts in Python pkg!

Thanks to the way we're now using the `./setup.py pre_install`
convention, there's no longer a need to check the artifacts in to the
Python package.

* move py templates BACK to abi-gen-templates

I got a little overzealous in the previous commit that moved ALL the
python stuff into the new packages/python-contract-wrappers folder.

* Update known-good test output: prettify

* add getABIEncodedTransationData to gen'd code

It was added into the template in the following commit, but the
corresponding checked-in generated code was not updated accordingly.

f51c4f9617

* Fix missed instance of languageSpecificName change

* abi-gen: refine pipeline for testing gen'd code

- generate wrappers for test fixture contracts (dummy, etc) not in `yarn
build` but in `yarn test`

- rename folder test/generated-test/generated-wrappers to
test/generated-test/known-good, and stop writing test output to there,
instead writing it to a new test/generated-test/output folder.

- sol-compile test fixture contracts in every test run

- run unit tests separately from tests of generated and built TypeScript
wrappers.  The existing `yarn run_mocha` will run unit tests, and
there's a new `yarn run_contract_wrapper_tests`.

* abi-gen: test Python gen [known test failures]

Also generate TypeScript wrapper test code into a TypeScript folder
(alongside the newly created Python folder).

Known-good code manually corrected (from generated code) to reflect
known problems that still need to be addressed.  Namely:
  - base contract and tx params should be imported from canonical
    package, not relative path. relative path is working for wrapping
    OUR contracts, but would not be usable in a more general
    context.
  - return type missing for some generated methods.

These outstanding problems are currently causing this test to fail.

* fix failing abi-gen test: missing return types

* fix failing abi-gen test: qualify imports

* in py wrapper, simplify base class initialization

per
https://github.com/0xProject/0x-monorepo/pull/1878#discussion_r299248641

* move 3rd party typings to typescript-typings

* make package python-contract-wrappers private

* make Xianny CODEOWNER of base-contract & templates

* abi-gen: clarify --help for --backend

* remove superfluous CHANGELOG entry
2019-07-03 11:01:01 -04:00
Xianny
f77aaaf2e0 Merge pull request #1907 from 0xProject/multilang/add-devdoc
Add devdoc to all contract artifacts
2019-07-02 13:22:04 -07:00
Chris Kalani
380835b151 Added Theo to team page 2019-07-02 12:21:06 -07:00
Xianny
857d91df85 Add dummy contract to test abi-gen-wrappers (#1881) 2019-06-28 15:42:36 -07:00
xianny
cd9a6b0de7 add example devdoc 2019-06-28 13:25:16 -07:00
xianny
86333f4928 add devdocs to all artifacts 2019-06-27 22:00:41 -07:00
F. Eugene Aumson
d1975bd5dd contract-artifacts: add devdoc to ERC20Token.json
Artifact changes crafted manually: re-generated artifacts from within
@0x/contracts-erc20, and then copied them into @0x/contract-artifacts,
but only committed the changes that added devdoc.

Modified @0x/contracts-erc20/compiler.json to include devdoc in the
hopes that next time contract-artifacts are re-generated en masse, the
devdoc output will just come along for the ride.

Compiling ERC20 TypeScript wrappers after adding devdoc to the artifacts
revealed some inconsistencies in the types.  ethereum-types'
DevdocOutput REQUIRED many fields which are not always present,
depending the devdoc contents itself.  Relaxing the requirement had some
ramifications.
2019-06-27 21:08:54 -07:00
David Sun
08b9f27eac Merge pull request #1904 from 0xProject/feature/website/add-dydx-explore
Adding dYdX to Explore page
2019-06-27 10:25:23 -07:00
F. Eugene Aumson
5b2cf8a776 Restore original Python label 2019-06-27 10:03:22 -04:00
F. Eugene Aumson
7394106880 Another attempt at the snake emoji 2019-06-27 09:13:49 -04:00
Chris Kalani
9134a7ae1e Prettier 2019-06-26 17:10:15 -07:00
Chris Kalani
c617e9f483 Adding dYdX to explore page 2019-06-26 17:06:53 -07:00
Xianny
545fcef716 Update autolabeler.yml 2019-06-26 12:42:53 -07:00
David Sun
e20fa3a1bf Merge pull request #1895 from 0xProject/feature/website/new-team-photos-2
Added new team headshots and a couple other small things
2019-06-25 11:32:30 -07:00
Chris Kalani
9d01b47d5b Added better advisor titles 2019-06-25 10:42:03 -07:00
Chris Kalani
fa4c34df41 Removed old StarkDEX announcement link 2019-06-25 10:33:32 -07:00
Chris Kalani
9f8ab4d626 Added new team photos to team page 2019-06-25 10:31:45 -07:00
Alex Browne
1971c9cecd Merge pull request #1879 from 0xProject/remove-albrow-codeowner-contract-tests
Remove @albrow as code owner for contract tests
2019-06-21 11:32:12 -07:00
Amir Bandeali
82f730831d Merge pull request #1863 from 0xProject/feat/contracts/static-call-proxy
Implement StaticCallProxy
2019-06-21 09:18:42 -07:00
Alex Browne
035167e5b7 Remove @albrow as code owner for contract tests 2019-06-20 13:59:17 -07:00
Amir Bandeali
323fb0a965 Bump solidity version pragma for undeployed AssetProxy contracts 2019-06-18 19:52:18 -07:00
Amir Bandeali
45aacf122f Fix StaticCallProxy comment and add sanity checks to TestStaticCallTarget 2019-06-18 19:52:18 -07:00
Amir Bandeali
5dcf7919fc Fix build errors 2019-06-18 19:52:18 -07:00
Amir Bandeali
f15560bd89 Update CHANGELOGs 2019-06-18 19:52:18 -07:00
Amir Bandeali
bf3ae730d6 Add fillOrder tests that use the StaticCallProxy 2019-06-18 19:52:18 -07:00
Amir Bandeali
92ce258bb4 Remove pipeline package from CI build 2019-06-18 19:52:18 -07:00
Amir Bandeali
5810e7df82 Add StaticCallProxy support to LibAssetData 2019-06-18 19:50:59 -07:00
Amir Bandeali
f2cbf4a561 Regenerate abi-gen-wrappers 2019-06-18 19:50:59 -07:00
Amir Bandeali
0c8bb2e675 Add unit tests for StaticCallProxy 2019-06-18 19:50:59 -07:00
Amir Bandeali
f51c4f9617 Allow getABIEncodedTransactionData to be called for read only contract methods 2019-06-18 19:50:59 -07:00
Amir Bandeali
5345f7c983 Add boilerplate for StaticCallProxy 2019-06-18 19:50:59 -07:00
Amir Bandeali
7d9e43b2e1 Add TestStaticCallTarget for testing StaticCallProxy 2019-06-18 19:50:59 -07:00
Amir Bandeali
570c1e1809 Add StaticCallAssetData encoding and decoding 2019-06-18 19:50:59 -07:00
Amir Bandeali
720d335b09 Add StaticCallProxy types and move 1155 method ABI into order-utils 2019-06-18 19:50:59 -07:00
Amir Bandeali
f0ecda1a48 Use more specific revert reason in ERC1155Proxy 2019-06-18 19:50:59 -07:00
Amir Bandeali
4ed111a7d4 Implement StaticCallProxy 2019-06-18 19:50:59 -07:00
Matthew Cadier Kim
fc257523c7 Remove pipeline package
* Remove entire readme for the pipelines package.

* remove pipeline everywhere

* bump circle ci
2019-06-18 17:01:53 -07:00
Xianny
9775f8d83c abi-gen should regenerate contract-wrappers if template files change (#1875) 2019-06-18 16:03:37 -07:00
Xianny
01a1b19556 Prune fields from EthBalanceChecker (#1876)
Remove forbidden fields from EthBalanceChecker
2019-06-18 14:53:26 -07:00
Xianny
bd228034fd Add workflow for copying compiled artifacts to 0x/contract-artifacts (#1842)
The contract artifacts should remain as standard compiler output during development. Fields should only be removed/added prior to being published in `@0x/contract-artifacts`. This PR adds the `yarn transform` script to `@0x/contract-artifacts` to facilitate this. 

Going forward, `abi-gen-templates` will have to support both standard artifacts and modified artifacts if they diverge, since the templates are used for `contract-artifacts`/`abi-gen-wrappers` (modified artifact) *and* development in all the `contracts/*` packages (standard artifact).

This PR makes the following changes to `contract-artifacts`:
- remove `evm.bytecode.linkReferences` from all artifacts
- remove `evm.deployedBytecode` and `sourceTreeHashHex` from Coordinator artifact
- prettify all artifacts (whitespace only changes)
2019-06-17 11:00:53 -07:00
Fabio B
2672a5c59f Merge pull request #1867 from 0xProject/fix/trezorSubprovider
Fix bug in Trezor implementation
2019-06-17 10:18:37 -07:00
Rick Morty
5f383430eb Add CHANGELOG entry 2019-06-15 21:27:09 -07:00
Rick Morty
66ec3e9f4d Hex should be true since the data returned expects it to be hex encoded 2019-06-15 21:23:40 -07:00
Fabio B
c269c427a6 Merge pull request #1865 from 0xProject/feature/ethBalanceChecker
contracts/dev-utils: Add EthBalanceChecker contract to monorepo
2019-06-13 09:37:40 -07:00
Fabio Berger
212855ebd8 Add missing import 2019-06-12 09:29:19 -07:00
Fabio Berger
8f78945a73 Update Python artifact 2019-06-12 09:15:40 -07:00
Fabio Berger
86d50cf597 Remove forbidden fields 2019-06-12 09:10:18 -07:00
Fabio Berger
8986d506a5 Have DevUtils inherit from EthBalanceChecker 2019-06-12 09:08:18 -07:00
Fabio Berger
3d2c945c35 Fix nits in contract 2019-06-12 09:08:04 -07:00
Fabio Berger
8206a3969f Add artifact to Python package 2019-06-11 08:51:51 -07:00
Fabio Berger
43afe67593 Add EthBalanceChecker contract to monorepo 2019-06-11 08:45:15 -07:00
Amir Bandeali
ecf939f8c8 Merge pull request #1848 from 0xProject/feat/contracts/order-validation-fillable-amount
Refactor OrderValidationUtils and create contracts-dev-utils package
2019-06-07 09:11:40 -07:00
Amir Bandeali
f0c4ccfa1e Remove multiple returns from devdoc comments, fix typos 2019-06-07 08:46:52 -07:00
Amir Bandeali
718d48b7d5 Fix linting errors and update CHANGELOGs 2019-06-07 08:46:20 -07:00
Amir Bandeali
d5e88677ae Update tests 2019-06-07 08:46:20 -07:00
Amir Bandeali
b1cfdc7a6a Return 0 balance/allowance if the call would otherwise revert 2019-06-07 08:46:20 -07:00
Amir Bandeali
5c5f815b20 Fix LibAssetData tests 2019-06-07 08:46:20 -07:00
Amir Bandeali
d9edb9675f Add tests for multiAssetData, remove tests for old functions 2019-06-07 08:46:20 -07:00
Amir Bandeali
be6fce5a89 Refactor contracts to only use allowances for AssetProxies (spender is no longer an input) 2019-06-07 08:46:20 -07:00
Amir Bandeali
12afeb30ae Move LibAssetData to DevUtils package 2019-06-07 08:46:20 -07:00
Amir Bandeali
23df406ff0 Fix package.json typos 2019-06-07 08:46:20 -07:00
Amir Bandeali
c9ecef4fc3 Cleanup tests 2019-06-07 08:46:20 -07:00
Amir Bandeali
62f0a867a8 Update CHANGELOGs 2019-06-07 08:46:20 -07:00
Amir Bandeali
f68b8d82e0 Move LibTransactionDecoder to dev-utils package 2019-06-07 08:46:20 -07:00
Amir Bandeali
6b7cb13e9a Move DevUtils contract into its own package 2019-06-07 08:46:19 -07:00
Amir Bandeali
613af6013a Update OrderValidationUtils to return fillableTakerAssetAmount and refactor tests 2019-06-07 08:46:19 -07:00
Amir Bandeali
0db56a781e Cleanup LibAssetData tests 2019-06-07 08:46:19 -07:00
Greg Hysz
fe7674b184 Merge pull request #1837 from 0xProject/fix/contracts/erc1155AssetProxyManualCopyFields
ERC1155 Proxy - Manually Copy Dynamic Fields from Calldata to Memory
2019-06-06 12:20:30 -07:00
Xianny
44a6fe7310 Note on updating contract artifacts (#1853) 2019-06-05 16:59:15 -07:00
Greg Hysen
46690f0c35 Made some comments more readable and fixed some spelling 2019-06-05 15:23:53 -07:00
Greg Hysen
cfc4e345cc ran prettier and updated changelog 2019-06-05 14:22:50 -07:00
Greg Hysen
c68278d824 Additional multiplication overflow checks 2019-06-05 14:09:09 -07:00
Greg Hysen
09600a71cd Added tests to assert that assetData is within the boundaries of calldata 2019-06-05 14:08:25 -07:00
Greg Hysen
d66ba70f5e Updated length to match comment + added explicit test 2019-06-05 14:08:25 -07:00
Greg Hysen
e7c4120d24 Validation checks for the length of asset data 2019-06-05 14:08:25 -07:00
Greg Hysen
1212e534a8 Adds boundary checks when copying dynamic fields (includes tests) 2019-06-05 14:08:25 -07:00
Greg Hysen
899d0f1e42 removed .only for tests 2019-06-05 14:08:25 -07:00
Greg Hysen
dde4ed3754 More readability for 1155 proxy 2019-06-05 14:08:25 -07:00
Greg Hysen
b596e02752 readability cleanup 2019-06-05 14:08:25 -07:00
Greg Hysen
d5afe696da removed .only from tests 2019-06-05 14:08:25 -07:00
Greg Hysen
976be66dee Scale values while copying from calldata 2019-06-05 14:08:25 -07:00
Greg Hysen
98c8a6387a manually copy ids, values, and data fields 2019-06-05 14:08:25 -07:00
Greg Hysen
be1b636e30 Improved readability of ERC1155 Proxy 2019-06-05 14:08:25 -07:00
Greg Hysen
8bae0b81aa Added ERC1155Proxy tests when data overlaps values in asset data 2019-06-05 14:08:25 -07:00
Greg Hysen
7ee19e1306 Added new tests for different lengths of receiver callback data, since we are now appending scaledValues after data. 2019-06-05 14:08:25 -07:00
Greg Hysen
626d0dfa93 Store scaled values and end of calldata in ERC1155 Asset Proxy 2019-06-05 14:08:25 -07:00
Greg Hysz
8453c616a5 Merge pull request #1852 from 0xProject/fix/contracts/expectTransactionFailedAsyncFalsePositives
Fixes false positives in `expectTransactionFailedAsync`
2019-06-05 13:51:59 -07:00
Greg Hysen
56bc2944d0 Fixed false positives in expectTransactionFailedAsync 2019-06-04 18:53:13 -07:00
Amir Bandeali
b2cf701e30 Merge pull request #1850 from 0xProject/removePipelineBuild
Remove pipeline package from build and from CI
2019-06-04 13:20:24 -07:00
Amir Bandeali
9a3b29acb7 Remove pipeline package from build and from CI 2019-06-04 12:58:31 -07:00
Fabio B
85b217f167 Merge pull request #1823 from 0xProject/fix/improveAssertionsAbiGen
Add parameter assertions to abi-gen-wrappers
2019-06-04 19:05:39 +01:00
Fabio Berger
a7700d6c22 Fix tests 2019-06-04 14:38:13 +01:00
Fabio Berger
1e274518dd Remove re-introduced deps 2019-06-04 13:28:13 +01:00
Fabio Berger
f4f8927c79 Update yarn lock 2019-06-04 13:26:35 +01:00
Fabio Berger
60b7890f16 Ensure assertions each get rendered on a new line 2019-06-04 13:26:35 +01:00
Fabio Berger
4d46290ef6 Fix failing tests 2019-06-04 13:26:35 +01:00
Fabio Berger
00f7e2cfc3 Fix linter errors 2019-06-04 13:26:35 +01:00
Fabio Berger
e742708261 Update abi-gen-wrappers 2019-06-04 13:24:29 +01:00
Fabio Berger
8c9de31c5c Add assertions to abi-gen templates and fix tests 2019-06-04 13:19:59 +01:00
Fabio Berger
2bf992f0ac Improve the NOTE in abi-gen utils 2019-06-04 13:18:02 +01:00
Fabio Berger
52a01bcc11 Fix linter errors 2019-06-04 13:18:02 +01:00
Fabio Berger
f250e03c40 Add missing deps 2019-06-04 13:18:01 +01:00
Fabio Berger
75acbfb042 Fi assertion type 2019-06-04 13:18:01 +01:00
Fabio Berger
740fd6f5d9 Rename txData to callData 2019-06-04 13:18:01 +01:00
Fabio Berger
c58306cd49 Add isNumberOrBigNumber assertion 2019-06-04 13:18:01 +01:00
Fabio Berger
985696631c Set liguist-generated to true 2019-06-04 13:18:01 +01:00
Fabio Berger
d8a3d7f920 Fix gitattributes so properly minimizes generate-wrappers in PR review 2019-06-04 13:18:01 +01:00
Fabio Berger
b6b96f0eee Tighten the assertion to hex string 2019-06-04 13:18:01 +01:00
Fabio Berger
3f037ef3cc Add PR number to CHANGELOG entries 2019-06-04 13:18:01 +01:00
Fabio Berger
5c2d3fb3da Update abi-gen-wrappers 2019-06-04 13:18:01 +01:00
Fabio Berger
84d38ea878 Add assertions to abi-gen templates and fix tests 2019-06-04 13:18:01 +01:00
Fabio Berger
6226aa0b23 2019-06-04 13:18:01 +01:00
Fabio Berger
72af35834b Update issue template to instruct submitter to prefix title with package name 2019-06-04 11:52:23 +01:00
David Sun
3019e3817f Merge pull request #1846 from 0xProject/feature/website/starkdex-announcement
Added StarkDEX announcement to homepage
2019-06-03 12:17:02 -07:00
Chris Kalani
da9e90faf0 Added new tab prop to announcement 2019-06-03 11:55:19 -07:00
Chris Kalani
e737395c2b Added StarkDEX announcement to homepage 2019-06-03 11:33:38 -07:00
Fabio B
5a33167594 Merge pull request #1844 from 0xProject/fix/docFixes
website: Doc Fixes
2019-06-03 18:20:09 +01:00
Fabio B
dfb7e50948 Merge pull request #1843 from 0xProject/fix/depSecurityIssues
Fixes the severe security vulnerability warnings on Github
2019-06-03 18:01:58 +01:00
Fabio Berger
b43c9f075c Fix version picker overflow 2019-06-03 12:55:33 +01:00
Fabio Berger
f42ce6adb5 Remove scrollbars onHover behavior as a short-term fix to get cmd-f working for all content on the page 2019-06-03 12:53:16 +01:00
Fabio Berger
bf533bbdbb Remove a bunch of packages from the Docs Home to declutter it a bit 2019-06-03 12:11:20 +01:00
Fabio Berger
9328729c4c Remove devnet mention from metacoin project 2019-06-03 12:02:36 +01:00
Fabio Berger
2e23a044ca Tell users of our Ethereum tools to use with Ganache now that it is supported and given our plans to deprecate devnet 2019-06-03 12:02:24 +01:00
Fabio Berger
691a3a1e72 Fix security vuln by using patched versions of deep-extend 2019-06-03 11:56:42 +01:00
Fabio Berger
fc40f9634b Upgrade tar-fs dep to version without critical security issue 2019-06-03 11:34:59 +01:00
Amir Bandeali
4969441f21 Merge pull request #1835 from 0xProject/feat/contracts/dev-utils
Update OrderValidator and create DevUtils contract
2019-06-01 13:40:10 -07:00
David Sun
d04d50794e Merge pull request #1841 from 0xProject/feature/website/remove-rahul
Removing Rahul from team page
2019-05-31 13:49:57 -07:00
Chris Kalani
5e1fbe34a9 Removed image file 2019-05-31 13:30:50 -07:00
Chris Kalani
2b75829a0c Removing Rahul from team page 2019-05-31 13:29:07 -07:00
Daniel Pyrathon
3b3fd0a3a2 Merge pull request #1803 from 0xProject/instant-callback-done
Added performedCallback attribute for Redux state, and added a hook f…
2019-05-29 14:29:14 -07:00
Daniel Pyrathon
1e4b61008a Merge branch 'development' of github.com:0xProject/0x-monorepo into instant-callback-done 2019-05-29 12:40:20 -07:00
David Sun
ffb71e9fd5 Merge pull request #1840 from 0xProject/fix/website/landing-kit/overflow-issue
Fixed bug with launch kit background
2019-05-29 11:56:54 -07:00
David Sun
c1aeb4bde6 fixing bug with background 2019-05-29 11:53:16 -07:00
David Sun
66bca5cd81 Merge pull request #1822 from 0xProject/feature/website/launch-kit-landing-page
[WIP] Launchkit landing page
2019-05-29 11:49:16 -07:00
F. Eugene Aumson
b68df3a067 Fix static-python-tests (#1839)
* Disable bandit linter on false positive lines

* Shorten docstring to fix linter error
2019-05-29 14:28:17 -04:00
Amir Bandeali
066f3bb646 Return MAX_UINT256 for unlimited allowances in all token standards 2019-05-28 17:01:54 -07:00
David Sun
661c334928 prettier 2019-05-28 12:58:42 -07:00
David Sun
a1895d4157 polished website 2019-05-28 12:58:42 -07:00
David Sun
1e7efe026a committing changes 2019-05-28 12:58:41 -07:00
David Sun
02e7da979a changes to hero 2019-05-28 12:58:41 -07:00
David Sun
bd2839110b Merge pull request #1833 from 0xProject/feature/website/resources-menu
Added Resources dropdown to main nav
2019-05-28 10:05:38 -07:00
Daniel Pyrathon
1bcb2697e7 added prettifier 2019-05-27 19:16:11 -07:00
Daniel Pyrathon
fdb9a664f5 Merge branch 'development' of github.com:0xProject/0x-monorepo into instant-callback-done 2019-05-27 18:54:46 -07:00
Daniel Pyrathon
8099c334c7 Merge branch 'master' of github.com:0xProject/0x-monorepo into instant-callback-done 2019-05-27 18:52:31 -07:00
Daniel Pyrathon
344d28ab78 added prettier 2019-05-27 18:45:08 -07:00
Daniel Pyrathon
5e41168305 removed final bit of performedCallback 2019-05-27 18:35:47 -07:00
Daniel Pyrathon
dd97669cdd removed other legacy code 2019-05-27 18:34:23 -07:00
Daniel Pyrathon
af75581659 removed legacy performedCallback system, and implemented new react-redux system 2019-05-27 18:30:29 -07:00
Amir Bandeali
3c08f5b86a Update CHANGELOGs 2019-05-26 18:00:03 -07:00
Amir Bandeali
7809cad6cb Fix linting errors and warnings 2019-05-26 17:59:53 -07:00
Amir Bandeali
3e59029966 Modify dev utils tests to pass 2019-05-26 17:20:10 -07:00
Amir Bandeali
24249bcb4d Add LibTransactionDecoder to DevUtils 2019-05-26 17:19:45 -07:00
Amir Bandeali
543011c3de Modify batch allowances to take an array of spenders 2019-05-26 17:19:01 -07:00
Amir Bandeali
4d9f2586d9 Remove redundant code, add signature checks to order validations, and create DevUtils contract 2019-05-26 16:15:56 -07:00
Amir Bandeali
7f94ebe362 Add signature validation checks to OrderValidator contract 2019-05-26 15:41:10 -07:00
Amir Bandeali
c9bf1eda54 Small readability and efficiency improvements 2019-05-26 15:33:55 -07:00
Amir Bandeali
2cd4d9004c Create LibAssetProxyIds 2019-05-26 14:39:31 -07:00
Chris Kalani
35cd0319d4 Prettier 2019-05-24 17:50:57 -07:00
Chris Kalani
899030e966 Fixed error, whups 2019-05-24 17:38:04 -07:00
Chris Kalani
15e3944d23 Removed redundant links, fixed linting issues 2019-05-24 17:23:05 -07:00
Chris Kalani
f1fbaedb0f Added Resources dropdown to main nav 2019-05-24 16:09:33 -07:00
Fabio Berger
cf04062a19 Publish
- 0x.js@6.0.10
 - @0x/asset-buyer@6.1.5
 - @0x/connect@5.0.10
 - @0x/contract-wrappers@9.1.4
 - @0x/dev-tools-pages@0.0.27
 - @0x/dev-utils@2.2.3
 - @0x/fill-scenarios@3.0.10
 - @0x/instant@1.0.24
 - @0x/metacoin@0.0.51
 - @0x/migrations@4.1.6
 - @0x/order-utils@8.1.1
 - @0x/order-watcher@4.0.11
 - @0x/pipeline@1.0.21
 - @0x/react-docs@2.0.12
 - @0x/react-shared@2.0.12
 - @0x/sol-compiler@3.1.8
 - @0x/sol-coverage@3.0.5
 - @0x/sol-doc@2.0.12
 - @0x/sol-profiler@3.1.7
 - @0x/sol-trace@2.0.13
 - @0x/sol-tracing-utils@6.0.12
 - @0x/subproviders@4.1.0
 - @0x/testnet-faucets@1.0.80
 - @0x/website@0.0.83
 - @0x/contracts-asset-proxy@2.1.5
 - @0x/contracts-coordinator@2.0.4
 - @0x/contracts-erc1155@1.1.6
 - @0x/contracts-erc20@2.2.5
 - @0x/contracts-erc721@2.1.6
 - @0x/contracts-exchange@2.1.5
 - @0x/contracts-exchange-forwarder@3.0.3
 - @0x/contracts-exchange-libs@2.1.6
 - @0x/contracts-extensions@3.1.5
 - @0x/contracts-multisig@3.1.5
 - @0x/contracts-test-utils@3.1.7
 - @0x/contracts-utils@3.1.6
2019-05-24 16:59:56 +01:00
Fabio Berger
2e922bf7db Updated CHANGELOGS 2019-05-24 16:59:43 +01:00
F. Eugene Aumson
741a731ecb Transaction decoder for Coordinator (#1802)
* Remove unused dependency from erc20/package.json

* Add LibTransactionDecoder

Yet unsupported functions include:
    cancelOrdersUpTo
    executeTransaction
2019-05-24 11:27:53 -04:00
Fabio Berger
91bff1976c Remove react deps from react-highlight in yarn.lock 2019-05-24 14:56:49 +01:00
Fabio B
fad500042a Merge pull request #1830 from 0xProject/feature/fixTrezorInefficiency
subproviders: Fix Trezor subprovider inefficiency
2019-05-24 01:24:40 +01:00
Fabio B
bdb2a01385 Update packages/subproviders/src/subproviders/trezor.ts
Co-Authored-By: Jacob Evans <dekz@dekz.net>
2019-05-24 00:52:33 +01:00
Fabio Berger
f372cd2d13 Add CHANGELOG entry for new Trezor subprovider 2019-05-23 15:52:53 +01:00
Fabio Berger
a435da910f Cache the derived key info since it does not change and currently we request it from the Trezor device for each request 2019-05-23 14:26:15 +01:00
Fabio Berger
f1d96d9673 Fix linter issues 2019-05-23 14:02:55 +01:00
Fabio Berger
45226ee1f6 Update yarn.lock 2019-05-23 14:00:57 +01:00
Fabio B
03b8d29740 Merge pull request #1431 from MarcZenn/feature/subproviders/trezor-subprovider
Feature/subproviders/trezor subprovider
2019-05-23 13:58:34 +01:00
Fabio B
80a4af249f Merge branch 'development' into feature/subproviders/trezor-subprovider 2019-05-23 13:14:09 +01:00
David Sun
900d444946 Merge pull request #1816 from 0xProject/feature/website/add-alex-kroeger
Added Alex Kroeger and removed Leo from team page :(
2019-05-20 10:19:01 -07:00
Fabio B
7ca9393d2d Merge pull request #1820 from 0xProject/fix/updateLaunchKitRepo
website/python-packages: Update 0x-launch-kit repo name to include `-backend`
2019-05-16 21:22:44 -03:00
Fabio Berger
b22d7bb310 Add backend to constant variable name as well 2019-05-16 21:21:54 -03:00
Fabio Berger
c742cdfe5c Update 0x-launch-kit repo name to include -backend 2019-05-16 16:30:48 -03:00
xianny
2d3fe02cd7 Publish
- 0x.js@6.0.9
 - @0x/asset-buyer@6.1.4
 - @0x/connect@5.0.9
 - @0x/contract-wrappers@9.1.3
 - @0x/fill-scenarios@3.0.9
 - @0x/instant@1.0.23
 - @0x/metacoin@0.0.50
 - @0x/migrations@4.1.5
 - @0x/monorepo-scripts@1.0.32
 - @0x/order-utils@8.1.0
 - @0x/order-watcher@4.0.10
 - @0x/pipeline@1.0.20
 - @0x/testnet-faucets@1.0.79
 - @0x/website@0.0.82
 - @0x/contracts-asset-proxy@2.1.4
 - @0x/contracts-coordinator@2.0.3
 - @0x/contracts-erc1155@1.1.5
 - @0x/contracts-erc20@2.2.4
 - @0x/contracts-erc721@2.1.5
 - @0x/contracts-exchange@2.1.4
 - @0x/contracts-exchange-forwarder@3.0.2
 - @0x/contracts-exchange-libs@2.1.5
 - @0x/contracts-extensions@3.1.4
 - @0x/contracts-multisig@3.1.4
 - @0x/contracts-test-utils@3.1.6
 - @0x/contracts-utils@3.1.5
2019-05-15 19:05:54 -04:00
xianny
7d61cb6bac Updated CHANGELOGS 2019-05-15 19:05:44 -04:00
xianny
a804433a7a must run npm with sudo 2019-05-15 18:08:28 -04:00
Xianny
11082320c2 add prepublish check for write permissions for npmjs packages (#1813) 2019-05-15 18:05:56 -04:00
xianny
9f9797b123 remove only flag 2019-05-15 18:02:32 -04:00
Xianny
05d34616b7 fallback to eth_sign if eth_signTypedData fails (#1817)
* fallback to eth_sign if eth_signTypedData fails

lots of wallets/web3providers still don't support the new signing methods
2019-05-15 18:01:55 -04:00
Jacob Evans
c7f474ada1 Merge pull request #1815 from 0xProject/bug/dutchAuctionDecode
Incorrect decode in DutchAuctionWrapper
2019-05-15 10:28:56 +02:00
Chris Kalani
c7328a63d0 Removing Leo's photo from images directory 2019-05-14 16:42:32 -07:00
Chris Kalani
db818794d5 Added Alex Kroeger and removed Leo :( 2019-05-14 16:34:19 -07:00
Jacob Evans
b4b34e4890 Update CHANGELOG 2019-05-14 22:25:30 +02:00
Jacob Evans
eec016380d Commit fix to decode 2019-05-14 19:57:48 +02:00
Jacob Evans
dcab272be0 Add a test for encoding/decoding dutch auction asset data 2019-05-14 19:20:27 +02:00
Fabio Berger
418d033a5c Publish
- 0x.js@6.0.8
 - @0x/asset-buyer@6.1.3
 - @0x/connect@5.0.8
 - @0x/contract-addresses@2.3.3
 - @0x/contract-wrappers@9.1.2
 - @0x/fill-scenarios@3.0.8
 - @0x/instant@1.0.22
 - @0x/metacoin@0.0.49
 - @0x/migrations@4.1.4
 - @0x/order-utils@8.0.2
 - @0x/order-watcher@4.0.9
 - @0x/pipeline@1.0.19
 - @0x/testnet-faucets@1.0.78
 - @0x/website@0.0.81
 - @0x/contracts-asset-proxy@2.1.3
 - @0x/contracts-coordinator@2.0.2
 - @0x/contracts-erc1155@1.1.4
 - @0x/contracts-erc20@2.2.3
 - @0x/contracts-erc721@2.1.4
 - @0x/contracts-exchange@2.1.3
 - @0x/contracts-exchange-forwarder@3.0.1
 - @0x/contracts-exchange-libs@2.1.4
 - @0x/contracts-extensions@3.1.3
 - @0x/contracts-multisig@3.1.3
 - @0x/contracts-test-utils@3.1.5
 - @0x/contracts-utils@3.1.4
2019-05-13 23:14:54 -03:00
Fabio Berger
e7a7713b80 Updated CHANGELOGS 2019-05-13 23:14:30 -03:00
xianny
52a580d845 fix dangling comma 2019-05-13 21:17:25 -04:00
xianny
ea42a0b5f5 version bump 2019-05-13 21:15:38 -04:00
xianny
a0b63da9a6 version bump 2019-05-13 20:57:26 -04:00
Xianny
8d9932fc42 add private key option to migration script (#1811) 2019-05-13 16:32:37 -07:00
Xianny
54be45bedc Update coordinator contracts (#1812)
* update coordinator contracts after redeploying
2019-05-13 16:32:16 -07:00
Jacob Evans
3c9d2a562b Merge pull request #1810 from 0xProject/bug/asset-buyer/remainingTakerAssetAmount
Fix bug where remainingTakerAssetAmount is not converted to BigNumber
2019-05-13 18:53:10 +02:00
Jacob Evans
654bd5175c Add asset-buyer to circleci 2019-05-13 18:19:08 +02:00
Jacob Evans
9db660cd3f Update CHANGELOG 2019-05-13 16:33:29 +02:00
Jacob Evans
9aeadff9bd Check for presence of metadata 2019-05-13 15:38:28 +02:00
Jacob Evans
cd631b789b Commit coverage directory 2019-05-13 13:30:44 +02:00
Jacob Evans
4d98408aaf Fix bug where remainingTakerAssetAmount is not converted to BigNumber 2019-05-13 13:28:59 +02:00
Fabio Berger
490aafba4e Publish
- 0x.js@6.0.7
 - @0x/abi-gen@2.0.10
 - @0x/abi-gen-templates@2.1.0
 - @0x/abi-gen-wrappers@4.3.0
 - @0x/assert@2.0.10
 - @0x/asset-buyer@6.1.1
 - @0x/base-contract@5.1.0
 - @0x/connect@5.0.6
 - @0x/contract-artifacts@1.5.1
 - @0x/contract-wrappers@9.1.0
 - @0x/contracts-gen@1.0.9
 - @0x/dev-tools-pages@0.0.26
 - @0x/dev-utils@2.2.2
 - @0x/fill-scenarios@3.0.6
 - @0x/instant@1.0.21
 - @0x/json-schemas@3.0.10
 - @0x/metacoin@0.0.48
 - @0x/migrations@4.1.2
 - @0x/monorepo-scripts@1.0.31
 - @0x/order-utils@8.0.0
 - @0x/order-watcher@4.0.7
 - @0x/pipeline@1.0.18
 - @0x/react-docs@2.0.11
 - @0x/react-shared@2.0.11
 - @0x/sol-compiler@3.1.7
 - @0x/sol-coverage@3.0.4
 - @0x/sol-doc@2.0.11
 - @0x/sol-profiler@3.1.6
 - @0x/sol-trace@2.0.12
 - @0x/sol-tracing-utils@6.0.11
 - @0x/sra-spec@2.0.10
 - @0x/subproviders@4.0.6
 - @0x/testnet-faucets@1.0.77
 - @0x/utils@4.3.3
 - @0x/web3-wrapper@6.0.6
 - @0x/website@0.0.80
 - @0x/contracts-asset-proxy@2.1.2
 - @0x/contracts-coordinator@2.0.1
 - @0x/contracts-erc1155@1.1.2
 - @0x/contracts-erc20@2.2.1
 - @0x/contracts-erc721@2.1.2
 - @0x/contracts-exchange@2.1.2
 - @0x/contracts-exchange-forwarder@3.0.0
 - @0x/contracts-exchange-libs@2.1.2
 - @0x/contracts-extensions@3.1.2
 - @0x/contracts-multisig@3.1.2
 - @0x/contracts-test-utils@3.1.3
 - @0x/contracts-utils@3.1.2
2019-05-10 14:12:32 -03:00
Fabio Berger
3cd31d49bb Updated CHANGELOGS 2019-05-10 14:12:19 -03:00
Fabio Berger
6dd78b8d35 Update exchange forwarder package version 2019-05-10 13:46:30 -03:00
Jacob Evans
bd51c34098 Merge pull request #1809 from 0xProject/order-watcher-weth-events
OrderWatcher Deposit/Withdraw events
2019-05-10 18:32:31 +02:00
Jacob Evans
0e758fadee Merge changelog entries 2019-05-10 17:53:09 +02:00
Jacob Evans
a67659ff8e Update changelog 2019-05-10 16:37:09 +02:00
Jacob Evans
d1203f90da Revert "Mutate ERC20 ABI to handle WETH Deposit and Withdrawl"
This reverts commit c5f6ebee18.
2019-05-10 16:32:17 +02:00
Jacob Evans
c5f6ebee18 Mutate ERC20 ABI to handle WETH Deposit and Withdrawl 2019-05-10 16:09:09 +02:00
Xianny
41cc5234c4 Add coordinator wrapper (#1792)
* wip first pass at coordinator wrapper

* implement cancels, helper methods, and more unit tests

* pin typeorm version in pipeline

* prettier

* add export to 0x.js

* generate ZeroEx transaction using EIP712

* update Coordinator artifact

* change OrderError -> TypedDataError
2019-05-09 15:48:41 -07:00
Amir Bandeali
c2d3e5f052 Merge pull request #1804 from yxliang01/patch-1
fix.docs(README.md): wrong package name
2019-05-09 10:06:48 -07:00
Jacob Evans
f944b95e32 Added CHANGELOG 2019-05-09 17:26:57 +02:00
Jacob Evans
0a5b919cd9 Add fix for failing test 2019-05-09 16:46:56 +02:00
Jacob Evans
b5f85c11fe Re-enable orderwatcher tests. Add test for WETH withdraw 2019-05-09 16:46:08 +02:00
Greg Hysz
5d44b5e913 Merge pull request #1808 from 0xProject/fix/abiEncoder/typo1
Fixed typo in ABI Encoder error message
2019-05-08 13:27:53 -07:00
Greg Hysen
dd1961d86c updated changelog 2019-05-08 11:22:06 -07:00
Greg Hysen
f3539bf448 fixed typo 2019-05-08 11:22:03 -07:00
David Sun
d831e559f0 Merge pull request #1805 from 0xProject/feature/website/remove-meta-description
Removed default descriptions for website SEO performance
2019-05-07 13:06:15 -07:00
David Sun
cc079660f3 Merge pull request #1800 from 0xProject/feature/website/add-patryk
Added Patryk to the team page
2019-05-07 13:05:58 -07:00
Greg Hysz
4460dac697 Merge pull request #1806 from 0xProject/fix/abiEncoder/multibyteStrings
Support for ABI Encoding multibyte strings (Fixes Issue #1723)
2019-05-07 13:01:53 -07:00
Greg Hysen
31190f921c fixed linter errors 2019-05-07 12:34:05 -07:00
Greg Hysen
22515d8dce updated changelog 2019-05-07 11:59:27 -07:00
Greg Hysen
a099d970a4 Fixes Issue #1723: ABI-Encoded strings can have incorrect length header (multibyte characters) 2019-05-07 11:52:14 -07:00
David Sun
95bb2c5504 removed actual meta tags for description 2019-05-06 16:07:01 -07:00
David Sun
0b1262cc4d removed default description 2019-05-06 15:59:55 -07:00
Xiao Liang
f9244f6f7e fix.docs(README.md): wrong package name 2019-05-07 04:14:19 +08:00
Daniel Pyrathon
9dd4ea1584 added prettifying operations on CI 2019-05-06 12:57:20 -07:00
Daniel Pyrathon
9d085cdb61 applied linting 2019-05-03 18:23:07 -07:00
Daniel Pyrathon
f00a2dbc59 added an unsubscribe handler 2019-05-03 18:05:40 -07:00
Daniel Pyrathon
20862d47ab Added performedCallback attribute for Redux state, and added a hook for callback whenever the transaction was successful 2019-05-03 17:27:26 -07:00
Chris Kalani
cfa1bf36de Fixing Greg's placement in the grid 2019-05-02 14:43:22 -07:00
Chris Kalani
c362b33b5a Added Patryk to the team page 2019-05-02 14:33:36 -07:00
F. Eugene Aumson
222a151eff bump versions, after recent publications (#1646)
* bump versions, after recent publications

* Changelog updates and version bumps

* Correct broken URL's in setup.py's

* Correct SRA Client description (append "Client")

* Add convenience script for uninstalling all pkgs

* Add documentation link to SRA Client README.md
2019-04-30 15:56:40 -04:00
Lawrence Forman
d6115cff25 Merge pull request #1797 from 0xProject/feature/abi-gen-templates/awaitTransactionSuccess
Add awaitTransactionSuccessAsync() to generated contract functions.
2019-04-30 14:13:13 -04:00
Lawrence Forman
6459522617 Merge pull request #1799 from 0xProject/fix/contracts/temporarily-disable-useDockerisedSolc
Disable `useDockerisedSolc` for all contracts `compiler.json`s until latest solc docker images are published
2019-04-30 14:12:31 -04:00
Lawrence Forman
16e1f0eea1 Disable useDockerisedSolc for all contracts compiler.jsons until 0.5.8 docker image is released. 2019-04-30 11:01:31 -04:00
F. Eugene Aumson
0564ac1530 Python doc polish (#1757)
* Exercise doctests as a test not as a linter

* Add a contract artifact doctest, and exercise it

* Clean up linter issues

* Change asset data decoding output type

Previously, it was a TypedDict, but that was causing problems.  Sphinx
seems to be broken, such that none of the fields of the class were being
rendered into the doc.

Thinking on it further, I decided that a NamedTuple makes more sense
here anyways, since tuples are immutable and this output value isn't
something someone should ever build or modify.  And, NamedTuple is
getting its fields properly rendered by Sphinx.

* Add type annotations to JSON schemas docs

* Add doc publish metadata file for middlewares pkg

* Improve documentation

Note that none of the changes to .py files impact functionality in any
way, because the changes are restricted to "docstrings", which to the
Python interpreter are simply no-op statements.

However, one caveat to that is that much of these docstring changes DO
affect the functionality of automated test runs, because all of the code
examples (blocks beginning with `>>> `) are "doctests", which are
exercised via the test framework.

The index.rst files are the top-level templates for generating the
documentation, and the "automodule"/"autoclass"/etc statements pull in
the docstrings from the source code.

* correct package name in doc URL

* Move sra_client module into zero_ex namespace

* Add functions to encode asset data to bytes

* Fix: SRA client was deserializing orders weirdly

The generated code was transforming the order structure, from the camel
case field name format in the spec, into the snake case field name
format expected by Python convention.  With this problem in place, the
only way to take an order from a relayer and send it to a contract (for
fill, cancel, etc) was to manually transform the field names, one by
one, into a new structure.

* Fix problem with Web3/JSON order conversion utils

* doctest: maker, trade ZRX for WETH, not vice versa

* Remove redundant test

* Construct order in native Python, not JSON

Then convert it to JSON before sending it to the relayer.

* doctest: simplify asset units

* Add doctests for filling and cancelling

* Minor doctetst copy edits; whitespace

* Rename function, and add optional parameter

* Tweak docstrings on JSON conversion functions.

* Demo asset data decoding to view asset pairs

* Demo selecting an order from the order book

And have taker take it.

* Rename variable

* Abstract ganache from examples

Doing that exposed excessive use of the verbose
NETWORK_TO_ADDRESSES[NetworkId.Ganache] construct, so simplified that,
which ripped into eliminating other temporary variables that had been
used to hold specific contract addresses.

Also cleaned up some misplaced import statements.

* Add missing SRA client doc publication metadata

* Ran prettier on new SRA client doc pub metadata

* Remove local env customizations in doc metadata

* Eliminate temporary variable

* Rename variable

* Show `pip install` in every package's doc

* Doc NetorkID & pagination params as int, not float

* Clean up unmatched parenthesis in docs
2019-04-30 07:44:51 -04:00
Amir Bandeali
b896f82282 Merge pull request #1798 from 0xProject/feat/clean-contracts
Add clean:contracts command to top level package.json
2019-04-29 16:07:45 -07:00
Amir Bandeali
d737d419d9 Add clean:contracts command to top level package.json 2019-04-29 16:06:00 -07:00
F. Eugene Aumson
0de2b6983b Add LibAssetData to contracts/asset-proxy (#1779)
* Stop restarting node unnecesssarily during test

* Add new, empty LibAssetData

* Support encoding & decoding of ERC20 asset data

* Support encoding & decoding of ERC721 asset data

* Support encoding & decoding of ERC1155 asset data

* Support encoding & decoding of multi-asset data

* Support querying ERC20 balance from asset data

* Support querying ERC721 balance from asset data

* Support querying ERC1155 balance from asset data

* Support querying balance from multi-asset data

* Support querying ERC20 allowance from asset data

* Support querying ERC721 allowance from asset data

* Support querying ERC1155 allowance from asset data

* In tests, wait for allowance set before checking

* Introduce temporary variable `assetDataBody`

* Handle edge case in multi-asset balance query

* Support multi-asset allowance query by asset data

* Move variable declaration up for readability.

* Make all solhint-disable's cite specific rules

And move the directives to the ends of lines whenever possible

* Rename query tests to include " by asset data"

* Extract test helper method

* Extract another test helper method

* Support batch queries of allowances & balances

* In LibAssetData.sol, use IERC1155, not ...Mintable

* Rename balance*() return vars: amount -> balance

* Fix bug in ERC721 balance query

Was using method balanceOf(), but needed to be using ownerOf().

getERC721TokenOwner() method lifted from
@0x/extensions/contracts/src/OrderValidator/OrderValidator.sol

* Reuse new en/decoders; avoid abi.decode().

* Start lowest allowance/balance from 0, not MAX_INT

* Properly implement ERC1155 balance querying

* Split lines for readability

* Also check isApprovedForAll in 721 allowance query

* Add neglected division of allowances by amounts

* Rename methods: balanceOf -> getBalance

* Rename methods: allowance -> getAllowance

* Add methods: getBalanceAndAllowance() & batch...()

* Rename return vars: amount -> allowance

* Add devdoc comments

* Rename batchGet* methods to getBatch*

* Remove refactoring relic

* Add revert messages to all require() calls

* Reduce gas usage for ERC1155 asset data decoding

* Don't use dockerized solc for ERC20 contracts

Because they demand solc version 0.4.26, and it seems as though the tag
for that version has been deleted from dockerhub.

Without this, @0x/contracts-erc20 was failing to build.

* Rename batch functions to use plurals

* Skip dockerized solc for contracts needing 0.4.26

I seems as though the tag for that version has been deleted from
dockerhub.

Without this, these contracts were failing to build.

* Make revert reasons follow snake case convention
2019-04-29 15:46:26 -04:00
Lawrence Forman
25628c34ee Add PR numbers to CHANGELOGs 2019-04-28 22:25:12 -04:00
Lawrence Forman
54fdccd397 Ran prettier. 2019-04-28 22:25:12 -04:00
Lawrence Forman
27af4a988d In @0x/abi-gen-wrappers: Regenerate contract wrappers. 2019-04-28 22:25:12 -04:00
Lawrence Forman
fddad131a2 In @0x/base-contract: Expose txHashPromise in PromiseWithTransactionHash.
In `@0x/abi-gen-templates`: Update `awaitTransactionSuccessAsync()` partial to expose `txHashPromise`.
2019-04-28 22:25:12 -04:00
Lawrence Forman
4d493eeebd In @0x/contracts-asset-proxy: Update tests to use contract-built-in awaitTransactionSuccessAsync(). 2019-04-28 22:25:12 -04:00
Lawrence Forman
14c1495a1a In @0x/abi-gen-templates: Make txData parameter optional in awaitTransactionSuccessAsync().
In `@0x/base-contract`: Make `PromiseWithTransactionHash` class compatible with ES5 transpiler.
In `@0x/abi-gen-wrappers`: Regenerate contract wrappers.
2019-04-28 22:25:12 -04:00
Lawrence Forman
49c029ddb3 In @0x/abi-gen-templates: Add txData parameter to awaitTransactionSuccessAsync.
In `@0x/abi-gen-templates`: Regenerate wrappers.
2019-04-28 22:25:12 -04:00
Lawrence Forman
ddbe142c4c In @0x/abi-gen-wrappers: Regenerate contract wrappers. 2019-04-28 22:25:12 -04:00
Lawrence Forman
4710b40e45 In @0x/abi-gen-templates: Add timeoutMs parameter to awaitTransactionSuccessAsync 2019-04-28 22:25:12 -04:00
Lawrence Forman
be0b296769 Fix more linter errors. 2019-04-28 22:25:12 -04:00
Lawrence Forman
0a0ee67740 Fix linter errors. 2019-04-28 22:25:12 -04:00
Lawrence Forman
943d648225 In @0x/abi-gen-wrappers: Regenerate wrappers. 2019-04-28 22:25:12 -04:00
Lawrence Forman
6d835f5cc1 In @0x/abi-gen-templates: Add awaitTransactionSuccessAsync() to transaction template. 2019-04-28 22:25:12 -04:00
Lawrence Forman
a59cd67acf In @0x/base-contract: expose a PromiseWithTransactionHash type. 2019-04-28 22:25:12 -04:00
Lawrence Forman
bbc06be091 Update contracts/exchange-forwarder to 0.5.5 (#1796)
* Cherry-pick updated `@0x/contracts-exchange-forwarder` from `3.0` branch.

* Add PR numbers to changelogs
2019-04-28 22:21:13 -04:00
David Sun
d303e9f347 Merge pull request #1795 from 0xProject/feature/website/new-sitemap.txt
Added new sitemap.txt
2019-04-26 20:03:59 -04:00
David Sun
85ee923d89 added new sitemap.txt 2019-04-26 20:01:55 -04:00
David Sun
fe6ba20ff5 Merge pull request #1788 from 0xProject/feature/website/seo+polish
Updated meta data for website
2019-04-26 16:24:31 -04:00
Fabio B
18acf50b12 Merge pull request #1789 from 0xProject/fix/order-watcher-race-condition
Fix OrderWatcher race-condition bug
2019-04-24 16:09:58 -05:00
Fabio B
509fabb61c Merge pull request #1733 from PaulRBerg/fix/monorepo-scripts/broken-yarn-command
Fix yarn command in monorepo-scripts
2019-04-23 18:19:33 -05:00
Fabio Berger
cc3378b4cd Add CHANGELOG entry 2019-04-23 18:07:12 -05:00
Fabio Berger
8d3ccf333d Fix race-condition bug 2019-04-23 18:05:33 -05:00
David Sun
520919b165 prettier+lint 2019-04-23 18:41:54 -04:00
Francesco Agosti
600b86dd31 Merge pull request #1787 from 0xProject/feature/instant/utility-methods
Export utility methods and data from instant
2019-04-23 13:21:27 -07:00
fragosti
9c3fdd2584 Export utility methods and data from instant 2019-04-23 13:03:31 -07:00
David Sun
73974cd90f added large card variant 2019-04-23 11:12:36 -04:00
David Sun
8a60b3b402 switched metadata for explore page 2019-04-23 11:05:14 -04:00
Francesco Agosti
59ed5ae6b7 Merge pull request #1785 from 0xProject/feature/instant/erc721-screen-support
Add overflow scroll to instant overlay & fix display bug
2019-04-22 20:39:15 -05:00
fragosti
c687385974 Fix token amount bug 2019-04-22 18:21:32 -07:00
fragosti
2f72e15ea7 Add overflow scroll to instant overlay 2019-04-22 18:07:20 -07:00
Brandon Millman
7ea99baeb2 Merge pull request #1781 from 0xProject/feature/website/add-rui-mason
Added Rui and Mason to the team page
2019-04-22 14:21:11 -07:00
Francesco Agosti
14f3d20772 Merge pull request #1768 from 0xProject/feature/instant/erc-721-support
Super MVP ERC 721 in Instant
2019-04-19 18:21:07 -05:00
fragosti
72f51df25f Change 0x site URL 2019-04-19 17:59:37 -05:00
fragosti
a94b58e304 Remove lodash is undefined 2019-04-19 17:57:06 -05:00
fragosti
d327fabf9c Remove empty switch statement in instant 2019-04-19 17:21:06 -05:00
fragosti
9e02888c74 Apply prettier 2019-04-19 17:05:09 -05:00
fragosti
98c9a847f3 Improve index.html 2019-04-19 16:58:42 -05:00
fragosti
a159f4c9d6 Make ERC721 image fitting more flexible 2019-04-19 16:49:37 -05:00
fragosti
b197731ed2 Add back mysterious change because of merge 2019-04-19 12:34:17 -05:00
fragosti
028f54fdf0 Fix linting errors 2019-04-19 12:28:28 -05:00
fragosti
de62a0f8ed Merge branch 'development' of https://github.com/0xProject/0x-monorepo into feature/instant/erc-721-support 2019-04-19 11:31:52 -05:00
Chris Kalani
a0fcc50a5f Added Rui and Mason to the team page 2019-04-18 11:58:31 -07:00
Brandon Millman
4f186e843c Merge pull request #1777 from 0xProject/feature/website/add-paul-vienhage
Added Paul to team page, updated 2 photos, cleaned up titles
2019-04-15 09:13:52 -07:00
Chris Kalani
df64c20587 Added Paul to team page, updated 2 photos, cleaned up titles 2019-04-12 16:00:24 -07:00
Jacob Evans
c78a602990 Publish
- 0x.js@6.0.6
 - @0x/abi-gen@2.0.9
 - @0x/abi-gen-templates@2.0.2
 - @0x/abi-gen-wrappers@4.2.0
 - @0x/assert@2.0.9
 - @0x/asset-buyer@6.1.0
 - @0x/base-contract@5.0.5
 - @0x/connect@5.0.5
 - @0x/contract-addresses@2.3.1
 - @0x/contract-artifacts@1.5.0
 - @0x/contract-wrappers@9.0.0
 - @0x/contracts-gen@1.0.8
 - @0x/dev-tools-pages@0.0.25
 - @0x/dev-utils@2.2.1
 - ethereum-types@2.1.2
 - @0x/fill-scenarios@3.0.5
 - @0x/instant@1.0.20
 - @0x/json-schemas@3.0.9
 - @0x/metacoin@0.0.47
 - @0x/migrations@4.1.1
 - @0x/monorepo-scripts@1.0.30
 - @0x/order-utils@7.2.0
 - @0x/order-watcher@4.0.6
 - @0x/pipeline@1.0.17
 - @0x/react-docs@2.0.10
 - @0x/react-shared@2.0.10
 - @0x/sol-compiler@3.1.6
 - @0x/sol-coverage@3.0.3
 - @0x/sol-doc@2.0.10
 - @0x/sol-profiler@3.1.5
 - @0x/sol-resolver@2.0.7
 - @0x/sol-trace@2.0.11
 - @0x/sol-tracing-utils@6.0.10
 - @0x/sra-spec@2.0.9
 - @0x/subproviders@4.0.5
 - @0x/testnet-faucets@1.0.76
 - @0x/tslint-config@3.0.1
 - @0x/types@2.2.2
 - @0x/typescript-typings@4.2.2
 - @0x/utils@4.3.1
 - @0x/web3-wrapper@6.0.5
 - @0x/website@0.0.79
 - @0x/contracts-asset-proxy@2.1.1
 - @0x/contracts-coordinator@2.0.0
 - @0x/contracts-erc1155@1.1.1
 - @0x/contracts-erc20@2.2.0
 - @0x/contracts-erc721@2.1.1
 - @0x/contracts-exchange@2.1.1
 - @0x/contracts-exchange-forwarder@2.1.1
 - @0x/contracts-exchange-libs@2.1.1
 - @0x/contracts-extensions@3.1.1
 - @0x/contracts-multisig@3.1.1
 - @0x/contracts-test-utils@3.1.2
 - @0x/contracts-utils@3.1.1
2019-04-11 17:00:06 +01:00
Jacob Evans
0acec57ba9 Updated CHANGELOGS 2019-04-11 16:59:38 +01:00
Xianny
7423028fea Replace lodash with built-ins where possible to reduce bundle size (#1766)
* add tslint rule to disallow lodash.isUndefined

* add tslint rule to disallow lodash.isNull

* apply fixes
2019-04-10 09:36:32 -07:00
David Sun
49d951b7be Merge pull request #1772 from 0xProject/bug/website-photos
Fix bug with photo name url
2019-04-09 23:44:55 -07:00
David Sun
a554c9518d changed photo name url 2019-04-09 23:43:23 -07:00
David Sun
f3c7ba445e Merge pull request #1771 from 0xProject/feature/website/new-team-photos
Website new team photos
2019-04-09 23:30:51 -07:00
David Sun
3abff41385 commiting photos 2019-04-09 23:08:29 -07:00
Ryan Chow
6c36832f0e Stop using deprecated web3.py interface (#1759)
* Refactor contract function call to support web3.py v5.0.0. (backwards compatible with v4)
2019-04-09 09:33:36 -04:00
fragosti
310c18707b Improve index.html 2019-04-05 16:57:13 -07:00
fragosti
422a4a5578 Add image component 2019-04-05 16:44:17 -07:00
fragosti
a995b2e1ae UI presenting NFT a bit more nicely 2019-04-05 16:25:53 -07:00
fragosti
90ad681a9e Extreme MVP of buying a ERC721 works 2019-04-05 15:55:10 -07:00
David Sun
2ff5c39712 Merge pull request #1767 from dave4506/fix/website/bug-sort-menu
Fix for menu z-index for explore
2019-04-05 15:03:13 -07:00
David Sun
ded849fd6d fix for menu z-index 2019-04-05 15:01:07 -07:00
David Sun
02f7064953 Merge pull request #1763 from dave4506/fix/website/flash-css-error
Fix Explore Issues with flash of css + other minor bugs
2019-04-05 14:57:19 -04:00
David Sun
1ddadfce1e added animation to tiles 2019-04-05 11:26:14 -07:00
David Sun
7720e5007c added animations to explore 2019-04-05 11:17:56 -07:00
David Sun
ccfd021796 switched header 'href' to 'to' 2019-04-05 11:17:56 -07:00
F. Eugene Aumson
fdcad84cee Delete merge conflict artifact (#1758) 2019-04-04 18:08:13 -04:00
Alex Browne
ad3e3b8421 Merge pull request #1755 from 0xProject/fix/circleci-yarn-permission-denied
Fix yarn permission denied errors in CircleCI
2019-04-04 13:21:36 -07:00
Jacob Evans
f67b4f8902 Merge pull request #1747 from 0xProject/feature/cut-the-package-fat
Cut the package fat! Part 1: Unwanted files
2019-04-04 14:26:23 +01:00
Jacob Evans
3c0d7319ba Update artifacts and remove top level artifacts 2019-04-04 12:30:41 +01:00
Jacob Evans
7f0aab6ec6 Remove unused deps 2019-04-04 12:30:41 +01:00
Jacob Evans
669578a926 Add contract-artifacts to circleci 2019-04-04 12:30:41 +01:00
Jacob Evans
fa1db64a8e Add a test to keep artifact sizes down 2019-04-04 12:30:41 +01:00
Jacob Evans
7cf60fa927 Remove sourcecode and opcodes from artifacts 2019-04-04 12:30:41 +01:00
Jacob Evans
75a0d3e494 Update all .npmignores 2019-04-04 12:30:41 +01:00
Jacob Evans
a98218ae22 Whitelist npmignore 2019-04-04 12:30:40 +01:00
Jacob Evans
10952e9dc4 Cut the package fat 2019-04-04 12:30:33 +01:00
Alex Browne
b36e23471b Fix yarn permission denied errors in CircleCI 2019-04-03 17:19:58 -07:00
Alex Browne
f45bf1c95b Merge pull request #1754 from 0xProject/fix/skip-geth-tests-ci
Disable Geth tests in CircleCI
2019-04-03 17:06:09 -07:00
Alex Browne
d4db2587aa Disable Geth tests in CircleCI 2019-04-03 16:38:58 -07:00
F. Eugene Aumson
62e6336a7d Fix race condition in CI runs of Python SRA client tests (#1751)
* In CI, don't start Launch Kit til Ganache is ready

* Re-enable Python SRA client tests

* For local testing, await service readiness
2019-04-03 18:22:26 -04:00
F. Eugene Aumson
2d8acd4711 Disable Python SRA tests against Launch Kit (#1750)
These tests have worked multiple times in Circle CI, but now they're not, and it seems to be misbehaving intermittently, so just disabling them for now.
2019-04-02 13:24:27 -04:00
Brandon Millman
d7d95be042 Merge pull request #1745 from 0xProject/fix/website/fix-codesandbox
Fix code sandbox link and 0x.js dep in website
2019-04-01 10:21:17 -07:00
David Sun
e3c97f0681 Merge pull request #1748 from dave4506/fix/website/pixure+bugs
Switched Pixura link
2019-04-01 08:59:20 -04:00
David Sun
1a4fa015b9 switched back to roboto 2019-04-01 08:54:02 -04:00
David Sun
63dacfaac5 switched pixura link 2019-04-01 08:48:46 -04:00
Brandon Millman
f7263ac2c6 Fix 0x.js dep 2019-03-29 16:54:41 -07:00
Brandon Millman
c7d7e1f0e3 Fix codesandbox link 2019-03-29 16:53:13 -07:00
Daniel Pyrathon
9c54b615f5 Merge pull request #1744 from 0xProject/feature/website/moar-Explore-updates
updates explore page
2019-03-29 16:28:02 -07:00
F. Eugene Aumson
69fe1aa981 Remove doctest skip for get_order method (#1743)
* Remove doctest skip for get_order method

* Set ganache env for Launch Kit in Circle CI

* Unpin Launch Kit version used in CI
2019-03-29 18:54:46 -04:00
rsingireddy
bfb3d19e3b fixes by way of yarn prettier 2019-03-29 15:45:49 -07:00
rsingireddy
0b4e62a63e updates explore page 2019-03-29 15:26:44 -07:00
David Sun
5cdbc03e71 Merge pull request #1676 from dave4506/website/feature/explore-page
Explore page
2019-03-28 21:10:57 -04:00
David Sun
16cd6dd25d removed .DS_Store 2019-03-28 20:54:00 -04:00
David Sun
fc71e7f99f updated to svg assets + new description 2019-03-28 20:51:56 -04:00
David Sun
e740380731 added changes for PR 2019-03-28 17:33:26 -04:00
Jacob Evans
f9921d2c91 Merge pull request #1714 from 0xProject/feature/order-utils/one-sided-transfer-validation
Simulate Maker transfer in order validation
2019-03-28 15:10:00 +01:00
Jacob Evans
d8bfc92cc5 Update documentation and changelog 2019-03-28 14:49:22 +01:00
Jacob Evans
1f2214f891 Major bump as this change could break existing orderbooks 2019-03-28 14:19:33 +01:00
Jacob Evans
50835e317f Update CHANGELOG 2019-03-28 14:00:40 +01:00
Jacob Evans
6c8d4dcc1e Allow simulation taker address to be specified 2019-03-28 14:00:40 +01:00
Jacob Evans
85a7efbd61 Change to accept maker amount 2019-03-28 14:00:40 +01:00
Jacob Evans
6b5ef10467 Remove unused imports 2019-03-28 14:00:39 +01:00
Jacob Evans
0bf46bfcb5 Re-use order relevant state 2019-03-28 14:00:39 +01:00
Jacob Evans
8b8dc7ac78 Update jsdoc 2019-03-28 14:00:39 +01:00
Fabio B
a017122c44 Update packages/contract-wrappers/src/types.ts
Co-Authored-By: dekz <dekz@dekz.net>
2019-03-28 14:00:39 +01:00
Fabio B
86a9a892d2 Update packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
Co-Authored-By: dekz <dekz@dekz.net>
2019-03-28 14:00:39 +01:00
Fabio B
f31a141d78 Update packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
Co-Authored-By: dekz <dekz@dekz.net>
2019-03-28 14:00:39 +01:00
Jacob Evans
fa67997424 Move order_utils from asset-buyer to order-utils package 2019-03-28 14:00:39 +01:00
Jacob Evans
a5f06c577d Remove unused pause 2019-03-28 14:00:38 +01:00
Jacob Evans
e575672877 Update CHANGELOGs 2019-03-28 14:00:38 +01:00
Jacob Evans
a34d5b29e8 Return eventually rejectedWith 2019-03-28 14:00:38 +01:00
Jacob Evans
91ec65da1b Await in tests to prevent clash in before blocks 2019-03-28 14:00:38 +01:00
Jacob Evans
ee8d40a66e Add IAssetProxy to python 2019-03-28 14:00:38 +01:00
Jacob Evans
38ac2e80ed Remove unused code 2019-03-28 14:00:38 +01:00
Jacob Evans
8b70762e34 Add a Test for an Untransferrable ERC20 token 2019-03-28 14:00:37 +01:00
Jacob Evans
18c613a611 Update comments 2019-03-28 14:00:37 +01:00
Jacob Evans
957f8c56a1 validateRemainingOrderAmountIsFillable 2019-03-28 14:00:37 +01:00
Jacob Evans
b16446877e only 2019-03-28 14:00:37 +01:00
Jacob Evans
9164d58dc7 Simulate maker transfer in order validation 2019-03-28 14:00:27 +01:00
Francesco Agosti
0beb2f9d3c Merge pull request #1740 from 0xProject/feature/website/add-Lawrence-change-Mel-role-change-Alex-Browne-role
adds lawrence forman to the website. changes mel role and alex browne…
2019-03-27 11:58:34 -07:00
Brandon Millman
ccdd66052a Merge pull request #1737 from 0xProject/feature/instant/update-infura
[instant] Add infura project id via env variables when bundling instant
2019-03-26 19:04:57 -07:00
Brandon Millman
518fd814b6 Merge branch 'development' into feature/website/add-Lawrence-change-Mel-role-change-Alex-Browne-role 2019-03-26 17:23:58 -07:00
rsingireddy
f49bb78dba adds lawrennce picture 2019-03-26 17:13:56 -07:00
rsingireddy
a54aa77d28 adds lawrence forman to the website. changes mel role and alex browne role 2019-03-26 16:51:07 -07:00
Brandon Millman
f85e443c9c Add instant.0x.org to host domains 2019-03-26 16:33:16 -07:00
Alex Browne
399e004e7f Merge pull request #1738 from 0xProject/fix/test-python-ci-failure-launch-kit-needs-pinning
Pin Launch Kit version in test-python CI task
2019-03-26 16:26:07 -07:00
Michael Huang
3099ba71eb New demos for Python packages (#1734)
End-to-end demos of constructing and signing an order and submitting it to a Relayer.  Docs are generated from the code, and include usage examples that are verified through automated testing.
2019-03-26 19:07:04 -04:00
F. Eugene Aumson
951fcf384c pin launch kit version in test-python ci task 2019-03-26 18:00:16 -04:00
Brandon Millman
c750368a3e Add infura project id via env variables when bundling instant 2019-03-26 14:17:57 -07:00
David Sun
3149d86855 lint + prettier 2019-03-26 16:55:10 -04:00
David Sun
3aaf21e34e removed banner and lint + prettier 2019-03-26 16:20:03 -04:00
David Sun
519c375a42 added responsive features 2019-03-26 16:20:03 -04:00
David Sun
3ed2c732bd added announcement banner 2019-03-26 16:20:02 -04:00
David Sun
0aa5550d0f Rearchitected Explore Page + added new features 2019-03-26 16:20:02 -04:00
David Sun
1bc8dd83d3 added settings dropdown 2019-03-26 16:20:02 -04:00
David Sun
c642cd6fed changed to popular 2019-03-26 16:20:01 -04:00
David Sun
f72918362d created most of the page's functionality 2019-03-26 16:20:01 -04:00
Leonid Logvinov
28c4ca73ab Merge pull request #1728 from ochikov/patch-6
Update constants.ts
2019-03-26 14:46:15 +01:00
Michael Huang
a256494ec8 Python contract wrappers (#1721) 2019-03-25 19:25:41 -04:00
Paul Berg
5fd359a64f Fix yarn command 2019-03-25 19:32:07 +00:00
Michael Huang
e043735362 Fix regex validation on numeric inputs (#1731)
* Fix regex validation on numeric inputs
2019-03-25 15:18:58 -04:00
Amir Bandeali
7010b1adb9 Merge pull request #1729 from 0xProject/feat/coordinator/functionVisibility
Modify function visibilities in Coordinator contract
2019-03-25 11:51:23 -07:00
Amir Bandeali
17ff262729 Update CHANGELOG 2019-03-25 10:11:37 -07:00
Amir Bandeali
1c18838cd8 Fix typos and add tests for decodeOrdersFromFillData 2019-03-25 10:11:37 -07:00
Amir Bandeali
55b87ae78d Make decodeOrdersFromFillData oublic and assertValidTransactionOrdersApproval internal 2019-03-25 10:11:37 -07:00
Amir Bandeali
e446e902f3 Remove TestMixins contract 2019-03-25 10:11:37 -07:00
Amir Bandeali
095b52e0b2 Make hashing methods public 2019-03-25 10:11:37 -07:00
Michael Huang
4f25ff6a50 local_message_signer middleware for web3.py (#1713) 2019-03-25 11:25:41 -04:00
ochikov
6242e0aeec Update constants.ts 2019-03-25 00:21:07 +02:00
Francesco Agosti
fde9fc9dd4 Merge pull request #1722 from 0xProject/fix/instant-polling
Unmount Instant when closing
2019-03-22 17:03:16 -07:00
fragosti
c481e42673 Reset yarn.lock 2019-03-22 16:21:02 -07:00
fragosti
5e228d7232 Merge branch 'development' of https://github.com/0xProject/0x-monorepo into fix/instant-polling 2019-03-22 15:03:15 -07:00
fragosti
6b8e40fdc9 Make unrender idempotent 2019-03-22 15:02:12 -07:00
Alex Svanevik
bca44bf9e3 Merge pull request #1684 from 0xProject/pull-github-data
Pull Github data
2019-03-22 18:33:40 +08:00
askeluv
08e49dcf2e Throttling to respect rate limits 2019-03-22 18:15:49 +08:00
Fabio Berger
0f45409b4d Publish
- 0x.js@6.0.5
 - @0x/abi-gen@2.0.8
 - @0x/abi-gen-wrappers@4.1.0
 - @0x/assert@2.0.8
 - @0x/asset-buyer@6.0.5
 - @0x/base-contract@5.0.4
 - @0x/connect@5.0.4
 - @0x/contract-addresses@2.3.0
 - @0x/contract-artifacts@1.4.0
 - @0x/contract-wrappers@8.0.5
 - @0x/contracts-gen@1.0.7
 - @0x/dev-tools-pages@0.0.24
 - @0x/dev-utils@2.2.0
 - @0x/fill-scenarios@3.0.4
 - @0x/instant@1.0.19
 - @0x/json-schemas@3.0.8
 - @0x/metacoin@0.0.46
 - @0x/migrations@4.1.0
 - @0x/monorepo-scripts@1.0.29
 - @0x/order-utils@7.1.1
 - @0x/order-watcher@4.0.5
 - @0x/pipeline@1.0.16
 - @0x/react-docs@2.0.9
 - @0x/react-shared@2.0.9
 - @0x/sol-compiler@3.1.5
 - @0x/sol-coverage@3.0.2
 - @0x/sol-doc@2.0.9
 - @0x/sol-profiler@3.1.4
 - @0x/sol-resolver@2.0.6
 - @0x/sol-trace@2.0.10
 - @0x/sol-tracing-utils@6.0.9
 - @0x/sra-spec@2.0.8
 - @0x/subproviders@4.0.4
 - @0x/testnet-faucets@1.0.75
 - @0x/types@2.2.1
 - @0x/typescript-typings@4.2.1
 - @0x/utils@4.3.0
 - @0x/web3-wrapper@6.0.4
 - @0x/website@0.0.78
 - @0x/contracts-asset-proxy@2.1.0
 - @0x/contracts-coordinator@1.1.0
 - @0x/contracts-erc1155@1.1.0
 - @0x/contracts-erc20@2.1.0
 - @0x/contracts-erc721@2.1.0
 - @0x/contracts-exchange@2.1.0
 - @0x/contracts-exchange-forwarder@2.1.0
 - @0x/contracts-exchange-libs@2.1.0
 - @0x/contracts-extensions@3.1.0
 - @0x/contracts-multisig@3.1.0
 - @0x/contracts-test-utils@3.1.1
 - @0x/contracts-utils@3.1.0
2019-03-21 17:07:20 +01:00
Fabio Berger
5469d3ec13 Updated CHANGELOGS 2019-03-21 17:07:04 +01:00
Fabio B
d12f8410b9 Merge pull request #1689 from 0xProject/addCoordinatorSupport
Add Coordinator contracts support in dev tools
2019-03-21 16:04:19 +01:00
Fabio Berger
704c52d229 Move @0x/contracts-test-utils dependency from devDep to deps to fix publish test 2019-03-21 15:33:47 +01:00
Fabio Berger
7dcdda14f5 modify types 2019-03-21 15:13:39 +01:00
Fabio Berger
0f59256ca7 merge development 2019-03-21 15:04:52 +01:00
Fabio Berger
ddee04e98c Try import instead of const 2019-03-21 14:46:47 +01:00
Steve Klebanoff
50f5002b71 Unmount component when closing 2019-03-21 14:43:31 +01:00
Fabio Berger
e866add4b0 Add artifacts to python packages 2019-03-21 14:33:54 +01:00
Fabio Berger
39b93b88c5 Fix prettier 2019-03-21 14:32:21 +01:00
Fabio Berger
deb7e95567 Revert change 2019-03-21 14:29:26 +01:00
Jacob Evans
91500501ce Merge pull request #1695 from 0xProject/feature/reduce-excess-block-polling
Reduce excess block polling when using Web3ProviderEngine
2019-03-21 13:37:07 +01:00
Jacob Evans
6a1caeb9a1 Update CHANGELOGs 2019-03-21 12:33:09 +01:00
Jacob Evans
cee7803c37 Remove IAssetProxy 2019-03-21 12:02:38 +01:00
Jacob Evans
4e8d0ac7cb Add IAssetProxy to python 2019-03-21 11:52:43 +01:00
Jacob Evans
47bbcb9935 Add HACK explanation 2019-03-21 11:52:43 +01:00
Jacob Evans
c0288c5f26 Fix changelog, remove migrate_testnet 2019-03-21 11:52:28 +01:00
Jacob Evans
18c2013625 Update contract CHANGELOGs 2019-03-21 11:51:53 +01:00
Jacob Evans
548089888d Remove excess web3providernegine polling from contracts 2019-03-21 11:50:19 +01:00
Jacob Evans
180c65cfeb Change all packages to use web3providerengine without excess polling 2019-03-21 11:50:19 +01:00
Jacob Evans
6a28e41bc8 Remove unnecessary type assertion 2019-03-21 11:50:19 +01:00
Jacob Evans
f9ef942a98 Use providerUtils.startProviderEngine to minimize the HACK 2019-03-21 11:50:18 +01:00
Jacob Evans
8272c7a74e Reduce excess block polling when using Web3ProviderEngine 2019-03-21 11:49:26 +01:00
Amir Bandeali
4e745489db Merge pull request #1720 from 0xProject/fix/remove-tec
Remove TEC package artifacts
2019-03-20 14:01:39 -07:00
Amir Bandeali
fc2625a0c0 Remove TEC package artifacts 2019-03-20 13:28:37 -07:00
Amir Bandeali
d0e43ebaf1 Merge pull request #1712 from merklejerk/fix/feature/contracts/LibAddressArray-tests
Fix LibAddressArray.indexOf() and add LibAddressArray tests.
2019-03-20 11:38:08 -07:00
Fabio Berger
879805e316 merge development 2019-03-20 17:07:02 +01:00
Fabio Berger
6845d2e0ef Add coordinator artifacts to python package 2019-03-20 16:56:08 +01:00
Fabio Berger
542d1c1c41 In-line the declaration 2019-03-20 16:27:13 +01:00
Greg Hysen
31568e7abb Merge pull request #1716 from 0xProject/contracts-asset-proxy/updateProxyId
ERC1155 ProxyId - ERC1155Token -> ERC1155Assets
2019-03-20 08:12:58 -07:00
Lawrence
4b2488b124 Ran prettier. 2019-03-20 10:58:25 -04:00
Lawrence
6ed1412bdd Remove unnecessary copy operation in TestLibAddressArray.testAppendRealloc().
Test explicitly for newly allocated address in LibAddressArray "append" tests.
2019-03-20 10:19:46 -04:00
Lawrence
78b9a45158 Add PR#s to changelogs. 2019-03-20 10:19:46 -04:00
Lawrence
b8925baa88 Add unit tests for contracts/utils/LibAddressArray.
Fix `LibAddressArray.indexOf` returning wrong index.
2019-03-20 10:19:46 -04:00
Lawrence
87fd3f2a82 Add RevertReason.InvalidFreeMemoryPtr to packages/types. 2019-03-20 10:19:46 -04:00
Fabio Berger
8af164dbd2 Attempt to fix type issue 2019-03-20 15:05:21 +01:00
Fabio Berger
c994afbf3c Fix Pylint 2019-03-20 15:02:49 +01:00
Fabio Berger
843caf86fb merge development 2019-03-20 14:32:26 +01:00
Fabio Berger
44eef5b0e0 Fix comment 2019-03-20 14:31:10 +01:00
askeluv
346c6fc590 Deal with failing Github API for issues 2019-03-20 12:41:56 +08:00
Greg Hysen
7ed3afe9f0 Updated function signature for ERC1155 ProxyId - ERC1155Token -> ERC1155Assets 2019-03-19 15:35:08 -07:00
Fabio Berger
2fbe0aed32 Fix Python tests 2019-03-19 14:53:43 +01:00
Alex Svanevik
3bdc1802cb Merge branch 'development' into pull-github-data 2019-03-19 14:31:31 +08:00
Fabio Berger
849ca58228 Fix PR number 2019-03-18 20:40:29 +01:00
Fabio Berger
9991fca2e5 Add changelog entry for contract-addressesa 2019-03-18 20:39:02 +01:00
Fabio Berger
9c7bdcfeef Add testnet and mainnet coordinator and coordinatorRegistry addresses 2019-03-18 20:37:01 +01:00
Fabio Berger
b5463d522b Add PR numbers 2019-03-18 17:30:10 +01:00
Fabio Berger
af0d830103 Update coordinator wrapper 2019-03-18 17:20:58 +01:00
Fabio Berger
d4187dffa3 Add createCoordinatorApprovalTypedData method to order-utils and use in Coordinator tests 2019-03-18 17:20:51 +01:00
Fabio Berger
a7f06f2be5 Update coordinator abi-gen-wrapper 2019-03-18 16:44:11 +01:00
Fabio Berger
7ff7d1a185 Merge branch 'development' into addCoordinatorSupport
* development:
  Fix order-watcher version
2019-03-18 12:00:18 +01:00
Fabio Berger
e3bc80e027 Merge branch 'development' into addCoordinatorSupport
* development: (93 commits)
  Linting
  Copied MixinAssetProxyDispatcher from exchange
  Added deployed contract packages to readme (and link to top-level readme)
  Bumped version of ERC1155Proxy to 0.5.5 + merged ERC20Proxy/ERC721Proxy/MultiAssetProxy dependencies into base contract files
  Make credits program participants 1 row
  Correct comment in `hashEIP712Message()` in `LibEIP712Domai.sol`. Merge janky changelog notes in `types` package. Correct changelog note in `coordinator` changelog.
  Add PR numbers to changelogs.
  additional zero outcome tests
  renamed perUnitValue to valueMultiplier
  added test for amount=0
  Adjusted changelog version since nothing has been published during this PR
  Added calldatacopy comment
  Do not revert if value or amount are zero. Only if amount is non-zero and there is an overflow.
  updated comment for calldatacopy
  yarn.lock for erc1155 proxy
  added exports for 1155 proxy
  Renamed tokenIds -> ids, tokenValues -> values, callbackData -> data to be consistent with the ERC1155 reference implementation.
  Rebased against development
  Ran prettier
  Updated changelogs and documentation for erc1155 proxy
  ...
2019-03-18 11:20:22 +01:00
askeluv
095882d016 Added Github issue entity 2019-03-13 16:30:10 +08:00
askeluv
1693506f80 name -> full_name + fixed error message for missing access token 2019-03-13 11:47:42 +08:00
Fabio Berger
9366fa3b45 Add CHANGELOG entries 2019-03-11 15:29:26 +01:00
Fabio Berger
d356e9e65f Add deploying Coordinator contracts to migration script 2019-03-11 14:38:51 +01:00
Fabio Berger
230ebffd0e Generate Coordinator contract wrappers and add to abi-gen-wrappers package 2019-03-11 14:38:35 +01:00
Fabio Berger
5eedc1edca Add Coordinator contracts to contract-artifacts package 2019-03-11 14:38:00 +01:00
askeluv
b88e42a52d Prettier 2019-03-11 14:33:17 +08:00
askeluv
8d1b27d130 Added entity tests 2019-03-11 14:31:51 +08:00
askeluv
1148d37102 Added comparison details to forks vs main branch 2019-03-11 14:10:08 +08:00
askeluv
88704ce417 Prettier 2019-03-08 20:07:26 +08:00
askeluv
9f69d2cb76 Third entity: Github fork 2019-03-08 20:04:03 +08:00
askeluv
55fd71c5e1 Second entity: Github pull request 2019-03-08 14:37:36 +08:00
askeluv
1991bd437f First entity: Github repo 2019-03-08 12:32:21 +08:00
MarcZenn
1bff790628 removed implicit cached accounts dependency 2019-01-14 11:03:33 -08:00
MarcZenn
0010ca3e03 updated error msg 2018-12-31 11:21:47 -08:00
MarcZenn
9edb5dae88 passing network id to constructor 2018-12-31 11:12:25 -08:00
MarcZenn
85b49096dc first requested changes 2018-12-31 11:04:19 -08:00
MarcZenn
a7eaa10220 remove trezor-connect module 2018-12-12 19:05:23 -08:00
MarcZenn
5a46ce55b6 prettier again 2018-12-12 18:32:30 -08:00
MarcZenn
dbebbecab1 restore CI builds 2018-12-12 18:20:30 -08:00
MarcZenn
c7593e66bf ran prettier 2018-12-12 15:02:41 -08:00
MarcZenn
d52dc69279 init trezor subprovider w/ trezor connect client api 2018-12-12 14:42:36 -08:00
MarcZenn
1c65fa212d restore unit tests 2018-12-11 16:59:25 -08:00
MarcZenn
be88eb00f8 clean up 2018-12-07 10:02:35 -08:00
marcmartinez
65c60f5386 [WIP] trezor subprovider 2018-12-07 07:06:40 -08:00
Fabio Berger
83a043e639 Merge branch 'development'
* development: (81 commits)
  Publish
  Updated CHANGELOGS
  print out error message and stack
  immediately return the patch incremented version if no changelog entries exist
  Put python package above TS/JS packages
  Reduce title size
  reduce text side in README
  Improve top-level README
  Fix prettier
  remove unused flag
  Add CHANGELOG entry
  Fix additional comments
  Improve comments
  Add migrations, contract-addresses and contract-artifacts to Developers home
  Create migrations doc reference page
  Add additional CHANGELOG to types package
  Add CHANGELOG entry
  Fix prettier
  Fix `SimpleContractArtifact` type
  Update abi-gen-wrappers
  ...
2018-11-21 21:19:31 +00:00
Fabio Berger
8175192f60 Merge branch 'development'
* development: (957 commits)
  fix(order_utils.py): publish docs to S3, not RTD (#1264)
  fix: make instant package private
  feat: refer to map file in postpublish configs
  feat: add new bundle name to bundle watch
  fix: tslint ignore rule in wrong place
  Update blog post feature
  Fix disclaimer on mobile
  Add smart contract docs to Developer Home
  Add Apache license link
  Fix capitalization in title
  Remove excess semi-colon
  Point directly to README for docs link
  Update icons
  Update LICENSE
  Fix disclaimer
  Add blogpost URL
  Add disclaimer
  Add launch kit to Developer home list of tools
  feat: Deploy contracts to Rinkeby
  fix: fix exceeds block gas limit error
  ...
2018-11-19 12:49:16 +00:00
Leonid Logvinov
7d2c975d73 Merge branch 'development' 2018-10-09 13:13:10 +02:00
Brandon Millman
e5153737d8 Merge branch 'development'
* development: (939 commits)
  Add asset-buyer to published packages section in README
  Publish
  Updated CHANGELOGS
  Update BuyQuote interface
  force re-build
  Add website build to instructions
  Revert format and re-add changes
  Build website in parallel with other tests since no other test relies on it being built to run
  Add back sourceMap support for both dev/prod
  Upgrade webpack
  Add missing default options
  Remove unused constants
  Add fee order with a takerFee
  Add additional order factory methods and refactor test to use them
  Add comments about buy quote calculation
  Update CHANGELOG
  Fix linter
  Add additional test for slippage
  Add buy_quote_calculator_test
  Add 0x Instant to bundle analysis
  ...
2018-10-04 16:06:05 -07:00
Alex Browne
88766a02c7 Merge branch 'development' 2018-08-13 18:42:09 -07:00
Fabio Berger
8162394797 Merge branch 'development'
* development: (175 commits)
  small README fixes
  Update docs list in README
  Add manual postpublish command to all public packages and update CHANGELOG.json
  Fix postpublish util to ignore namespace
  Fix release notes bug
  Should print out `lerna publish` stdout so we can see if anything went wrong
  Publish
  Updated CHANGELOGS
  Generate CHANGELOG.json files
  Fix hasty find/replace
  Default to 4sp
  Update moment, no longer need separate moment types
  Move prettify command to utils and also call it on CHANGELOG.md
  Add prettier run on generated CHANGELOG.json and fix scripts
  Remove semi-colons from monorepo-scripts package.json
  Get rid of ; in top-level package.json
  Fix TSLint error
  Make dry-run configurable from top-level package.json
  Improve naming
  Run prettier, update deployer CHANGELOG
  ...
2018-04-02 21:23:07 +09:00
Fabio Berger
fd001186dd Merge branch 'development'
* development:
  Update deployer version since manual re-publish
  Add new entry into CHANGELOG
  Fix bad merge
  Update yarn.lock
  Change title
  Add Blake and Zach to About page
  Re-size Jacob and Tom's images
  WIP
  Fix bad merge
  Fix yarn.lock
  Fix quotation marks
  Update README and CHANGELOG
  Add scaffolding for sra-report collection unit tests
2018-03-20 11:11:07 +00:00
Fabio Berger
128fef8838 Merge branch 'master' of github.com:0xProject/0x-monorepo
* 'master' of github.com:0xProject/0x-monorepo:
2018-03-19 01:18:01 +01:00
Fabio Berger
1e25a0654a Merge branch 'development'
* development:
  Manually publish 0x.js back to a working state
  Publish
  Publish
  Fix 0x.js assets
  Remove assets from connect and _bundles from packages that don't generate the folder
  Publish
  Fix packages that aren't working as expected
2018-03-19 01:17:37 +01:00
Fabio Berger
82b0ff6008 Merge branch 'development'
* development: (269 commits)
  Make new packages default to public on publish
  Add new public packages to top-level README
  Update top-level package.json
  Fix incorrect new versions
  Fix path to assets
  Publish
  Updated CHANGELOGS
  Fix quotation marks
  Add a complex test for ast visitor
  Move opcodes to constants
  Fix issue with bundling subproviders for the browser by ignoring the `ganache-core` dependency
  Add changelog entry about pragma addition
  Add pragma above command-line script
  Add tests for sol-cov
  Updated CHANGELOGs
  Add SignedOrder, Order, and ECSignature types to the types package
  Keep console.log in monorepo-scripts
  Enable coverage for all other packages with tests
  Fix parallel coverage results reporting
  Fix linter issuesx
  ...
2018-03-18 20:14:02 +01:00
Brandon Millman
ca7c3630f9 Merge branch 'development'
* development: (114 commits)
  Prettier sra-report README
  Add new packages to top level README
  Updated @0xproject/utils in top level package.json
  Publish
  Updated CHANGELOGs
  Detail tests in the README
  Add support for ropsten and rinkeby
  Fix yarn.lock
  Update list of packages and organize them alphabetically
  Fix prettier issues
  Add support for going back to previous hashes via the browser back button to wiki
  Scroll to previous hashed elements when user clicks back button
  Add back strict null checks to react-shared package and fix issues
  remove ability to have implicit dependencies and add missing deps
  update license
  remove no-implicit-this
  Add example & screenshot to npmignore
  Remove `;` to be nice to windows users
  Use unencoded @ symbol, browser will fix
  Fix external type links
  ...
2018-03-08 10:47:23 -08:00
Brandon Millman
260bb8218f Merge branch 'master' of github.com:0xProject/0x-monorepo
* 'master' of github.com:0xProject/0x-monorepo: (171 commits)
  Fix bugs in postpublish_utils.js
  Update @0xproject/utils in top-level package.json
  Changelog tweaks
  Publish
  Updated CHANGELOGS
  Fix typo
  Add PR number to changelog entry
  Add changelog update to subproviders package
  Add `numberOfAccounts` param to `LedgerSubprovider` method `getAccountsAsync` and add tests
  Remove unnecessary type assertion
  Fix comments
  Add comments
  Don't need any external packages for 0x connect docs yet
  Instead of adding `@0xproject/types` to tsconfig.json, let's only add it when calling TypeDoc
  Fix styling
  Make prettier ignore postpublish_utils
  Update yarn.lock
  Update yarn.lock
  Update all mentions of the repo name being `0x.js` to `0x-monorepo`
  Add hack comment
  ...
2018-03-08 10:47:13 -08:00
Fabio Berger
a691de7d55 Merge branch 'development'
* development:
  Fix bugs in postpublish_utils.js
2018-03-05 06:13:18 +01:00
Fabio Berger
5674c484e2 Merge branch 'development'
* development: (175 commits)
  Update @0xproject/utils in top-level package.json
  Changelog tweaks
  Publish
  Updated CHANGELOGS
  Fix typo
  Add PR number to changelog entry
  Add changelog update to subproviders package
  Add `numberOfAccounts` param to `LedgerSubprovider` method `getAccountsAsync` and add tests
  Remove unnecessary type assertion
  Fix comments
  Add comments
  Don't need any external packages for 0x connect docs yet
  Instead of adding `@0xproject/types` to tsconfig.json, let's only add it when calling TypeDoc
  Fix styling
  Make prettier ignore postpublish_utils
  Update yarn.lock
  Update yarn.lock
  Update all mentions of the repo name being `0x.js` to `0x-monorepo`
  Add hack comment
  Add comment about typeDoc versions
  ...
2018-03-04 19:38:55 +01:00
Brandon Millman
9286dc284c Merge branch 'development'
* development:
  Publish
  Updated CHANGELOGs
  Do not JSON parse empty reponse
  Fix incorrect comment on WebSocketOrderbookChannel constructor
  Fix broken postpublish script in connect
2018-02-16 23:00:54 -07:00
Brandon Millman
624b71bd39 Merge branch 'development'
* development: (45 commits)
  Updated top level @0xproject/utils dependency
  Publish
  Updated CHANGELOGs
  Add an enforced minimum for the heartbeat interval
  Add Rinkeby network to smart contract docs
  Updated CHANGELOG
  Add configurable heartbeat to WebSocketOrderbookChannel
  remove hard-coded color
  Remove section links until they go somewhere
  Add more padding on top of section title
  Add hack comment explaining param count short-cut
  replace repeated conditionals with variable
  Remove unneeded props
  use const over hard-coding
  uncomment dev logic
  Re-design docs pages
  Add icons for all doc pages
  Re-designed Wiki and half-redesigned docs pages
  Prettier fixes
  Rename variables
  ...
2018-02-16 10:01:01 -07:00
Fabio Berger
b7ea605a3b Merge branch 'development'
* development: (57 commits)
  Update utils in top-level package.json
  Publish
  Fix version in CHANGELOG
  Update changelog version
  Fix changelog version
  Fix changelogs
  Add `yarn-error.log` to all .npmignore
  Add PR number to CHANGELOGs
  ignore all files starting with dots in all sub-packages
  Remove top level .npmignore
  Add npmignore to web3-wrapper and update CHANGELOG
  Add npmignore and remove .gitignore
  Add npmignore to utils and update CHANGELOG
  Add npmignore to types and update CHANGELOG
  cleanup npmignorex
  Add npmignore to subproviders and update CHANGELOG
  Add npmignore to json-schemas and update CHANGELOG
  Add npmignore to dev-utils and update CHANGELOG
  Add npmignore to deployer along with a changelog
  Add tslint.json to deployer package and fix all tslint issues
  ...
2018-02-09 16:36:13 -08:00
Brandon Millman
489a787de8 Merge branch 'development'
* development: (199 commits)
  Update @0xproject/utils version in top level package.json
  Publish
  Update CHANGELOGs
  Fix wiki styling
  Prettier
  Addressed review comments
  Update Subprovider README
  Fix Remco's github name in CODEOWNERS
  Only show faucet error if not on a testnet
  Organize async task queues by network
  Fix ABI error message
  Move isTestNetwork into utils and also check it from showing ZRX request button
  Stop using definite assignment assertion cause prettier doesn't handle that
  Special-case ZRXToken snake case conversion
  Fix linter errors
  Generate contract wrappers on pre-build
  Add missing async
  Remove noImplicitThis
  Tslint disable no-consecutive-blank-lines in generated files
  Change compiled sources in contracts
  ...
2018-02-07 13:37:53 -08:00
Fabio Berger
84150036ed Merge branch 'development'
* development: (78 commits)
  Publish
  Add PR number
  Add config file specifically in prettier command and fix files
  Fix prettier
  Fix prettier
  Add shouldAddPersonalMessagePrefix param to signOrderHashAsync instead of trying to infer whether to add it or not from the nodeVersion
  Publish
  Move @0xproject/types to dependencies
  Updated web3-typescript-typings changelog
  Fixed getTransactionReceipt not returning null
  Run prettier
  Update changelog
  Add Rinkeby addresses to artifacts
  Fix bad merge on package.json
  Respond to GH comments and add /info endpoint
  Publish
  Update yarn.lock
  Update the CHANGELOG
  Fix the bug making it impossible to specify the custom ZRX address
  Change package name to @0xproject/testnet-faucets
  ...
2018-01-30 13:59:47 +01:00
Brandon Millman
619123720c Merge branch 'development'
* development: (31 commits)
  Publish
  Update CHANGELOG
  Fix the typos
  Added PR number to web3 typings changelog
  Update the CHANGELOG
  Fix fillOrdersUpTo balances validation
  Add a regression test for fillUpToValidation
  Fix web3 typing defaultAccount not allowing `undefined`
  Sort packages alphabetically in README
  Add postpublish scripts
  Return after checking for an error and add an explanatory comment
  Stop appending /v0 to HttpClient api endpoint urls
  Add chai-as-promised-typescript-typings
  Remove redundant type refs
  Improve HttpClient errors
  Add web3-typescript-typings and chai-as-promised-typescript-typings to the main monorepo
  Import chai-as-promised-typescript-typings
  Fix @bmilman linkedin link
  Add new team photos
  Add a CHANGELOG to a website
  ...
2018-01-17 22:49:31 -08:00
Leonid Logvinov
cc98ff9fe6 Merge branch 'development' 2018-01-11 13:17:12 +01:00
Leonid Logvinov
39d159f38c Merge branch 'development' 2017-12-20 17:25:03 +01:00
Leonid Logvinov
ca8eb90cec Merge branch 'development' 2017-12-15 16:07:05 +01:00
Leonid Logvinov
f8e3e28d85 Merge branch 'development' 2017-12-14 17:52:23 +01:00
Leonid Logvinov
4d868489bd Merge branch 'development' 2017-12-13 16:06:31 +01:00
Brandon Millman
b06f09f6af Merge branch 'development'
* development: (115 commits)
  Publish
  Add scope to abi-gen dependency in 0x.js
  Add @0xproject scope to abi-gen package name
  Add yarn install to lerna:publish command
  Make contracts package private
  Update connect changelog
  remove console.log
  Update README.md
  Fix unit test
  Add missing params
  Debug CircleCi failure
  Update yarn.lock
  Inline network module
  Add todo
  Stop supporting different file extensions in abi-gen
  Refactor networkId out of web3Wrapper
  Update connect types in preperation for publishing
  Add link to random id generator
  Remove `prebuild` command and add `test:circleci`
  Make sure we don't pass empty maker into getOrderHashHex
  ...
2017-12-08 14:21:59 -08:00
Brandon Millman
bf00f5f945 Merge branch 'development'
* development: (156 commits)
  Publish
  Update CHANGELOG.md
  Redeclare Order, SignedOrder, and ECSignature types in connect, remove 0x.js dependency
  Add SignedOrder and TokenTradeInfo to public interface and fix a HttpClient comment
  Add TokenTradeInfo to public types
  Rename @0xproject/connect to 0x Connect
  Rename packageName to displayName for clarity
  Fix phantom `Contracts` section issue
  Add 0x Connect to footer
  Update 0x.js to 0.27.1
  Fix connect documentation introduction and installation wording
  Lock the 0x.js version used in website
  rename for clarity
  remove unused code
  Add 0x Connect Docs to the menu and topBar
  Add connect docs
  Add subPackageName and get rid of hard-coded 0x.js in sourceLink
  Publish
  Refactor the topLevel documentation react components for 0x.js and Smart contracts into a single component
  Export TransactionOpts type
  ...
2017-11-29 12:55:34 -08:00
Brandon Millman
6ceb6cc301 Merge branch 'development'
* development: (143 commits)
  Fix connect CHANGELOG version
  Publish
  Fix npm auth issues
  Revert "Publish"
  Publish
  Add actual version to CHANGELOG
  Add blockchainLifecycle management to the ExpirationWatcher test
  Update connect CHANGELOG.md in preperation for publishing
  Add TODO comment before BigNumber.config() call
  Prepare connect package for publishing
  Last renames
  Refactor while condition
  Fix tests
  Fix a typo in  postpublish utils tags -> tag
  Publish
  Revert "Publish"
  Publish
  Add instanceOf assertion
  Rename toDecimal to hexToDecimal
  Add PR numbers
  ...
2017-11-22 15:23:27 -08:00
Fabio Berger
00a6afaa8e Re-add changelog for 0x.js 2017-11-13 16:27:43 -05:00
1169 changed files with 49837 additions and 35399 deletions

View File

@@ -11,9 +11,14 @@ jobs:
steps:
- checkout
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
- run:
# HACK(albrow): Without this, yarn commands will sometimes
# fail with a "permission denied" error.
name: Set npm path
command: npm set prefix=/home/circleci/npm && echo 'export PATH=$HOME/circleci/npm/bin:$PATH' >> /home/circleci/.bashrc
- run:
name: install-yarn
command: sudo npm install --global yarn@1.9.4
command: npm install --global yarn@1.9.4
- run:
name: yarn
command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
@@ -24,6 +29,10 @@ jobs:
key: repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo
- save_cache:
key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/python-contract-wrappers/generated
build-website:
resource_class: medium+
docker:
@@ -42,17 +51,7 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-multisig
- run: yarn wsrun test:circleci @0x/contracts-utils
- run: yarn wsrun test:circleci @0x/contracts-exchange-libs
- run: yarn wsrun test:circleci @0x/contracts-erc20
- run: yarn wsrun test:circleci @0x/contracts-erc721
- run: yarn wsrun test:circleci @0x/contracts-erc1155
- run: yarn wsrun test:circleci @0x/contracts-extensions
- run: yarn wsrun test:circleci @0x/contracts-asset-proxy
- run: yarn wsrun test:circleci @0x/contracts-exchange
- run: yarn wsrun test:circleci @0x/contracts-exchange-forwarder
- run: yarn wsrun test:circleci @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-extensions @0x/contracts-asset-proxy @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-coordinator @0x/contracts-dev-utils
test-contracts-geth:
docker:
- image: circleci/node:9-browsers
@@ -64,17 +63,7 @@ jobs:
- repo-{{ .Environment.CIRCLE_SHA1 }}
# HACK(albrow): we need to sleep 10 seconds to ensure the devnet is
# initialized
- run: sleep 10 && TEST_PROVIDER=geth yarn wsrun test @0x/contracts-multisig
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-utils
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-exchange-libs
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-erc20
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-erc721
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-erc1155
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-extensions
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-asset-proxy
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-exchange
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-exchange-forwarder
- run: TEST_PROVIDER=geth yarn wsrun test:circleci @0x/contracts-coordinator
- run: sleep 10 && TEST_PROVIDER=geth 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-extensions @0x/contracts-asset-proxy @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-coordinator @0x/contracts-dev-utils
test-publish:
resource_class: medium+
docker:
@@ -95,20 +84,6 @@ jobs:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn test:generate_docs:circleci
test-pipeline:
docker:
- image: circleci/node:9
- image: postgres:11-alpine
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: ZEROEX_DATA_PIPELINE_TEST_DB_URL='postgresql://postgres@localhost/postgres' yarn wsrun test:circleci @0x/pipeline
- save_cache:
key: coverage-pipeline-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/pipeline/coverage/lcov.info
test-rest:
docker:
- image: circleci/node:9-browsers
@@ -119,6 +94,8 @@ jobs:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-test-utils
- run: yarn wsrun test:circleci @0x/abi-gen
- run: yarn wsrun test:circleci @0x/asset-buyer
- run: yarn wsrun test:circleci @0x/contract-artifacts
- run: yarn wsrun test:circleci @0x/assert
- run: yarn wsrun test:circleci @0x/base-contract
- run: yarn wsrun test:circleci @0x/connect
@@ -143,6 +120,10 @@ jobs:
key: coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/assert/coverage/lcov.info
- save_cache:
key: coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/asset-buyer/coverage/lcov.info
- save_cache:
key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -201,21 +182,27 @@ jobs:
- image: circleci/python
- image: 0xorg/ganache-cli:2.2.2
- image: 0xorg/launch-kit-ci
command: |
yarn start:ts -p 3000:3000
environment:
RPC_URL: http://localhost:8545
NETWORK_ID: 50
WHITELIST_ALL_TOKENS: True
command: bash -c "until curl -sfd'{\"method\":\"net_listening\"}' http://localhost:8545 | grep true; do continue; done; forever ts/lib/index.js"
steps:
- checkout
- run: sudo chown -R circleci:circleci /usr/local/bin
- run: sudo chown -R circleci:circleci /usr/local/lib/python3.7
- restore_cache:
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: |
cd python-packages
python -m ensurepip
./pre_install
./install
- save_cache:
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
paths:
- '/usr/local/bin'
- '/usr/local/lib/python3.7/site-packages'
@@ -256,14 +243,14 @@ jobs:
- run: sudo chown -R circleci:circleci /usr/local/bin
- run: sudo chown -R circleci:circleci /usr/local/lib/python3.7
- restore_cache:
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: |
cd python-packages/order_utils
python -m ensurepip
python -m pip install .
- save_cache:
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
paths:
- '/usr/local/bin'
- '/usr/local/lib/python3.7/site-packages'
@@ -284,11 +271,14 @@ jobs:
- run: sudo chown -R circleci:circleci /usr/local/bin
- run: sudo chown -R circleci:circleci /usr/local/lib/python3.7
- restore_cache:
key: deps9-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: |
python -m ensurepip
cd python-packages
./pre_install
./install
./lint
static-tests:
@@ -318,6 +308,9 @@ jobs:
- restore_cache:
keys:
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-asset-buyer-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
@@ -390,12 +383,11 @@ workflows:
- test-contracts-ganache:
requires:
- build
- test-contracts-geth:
requires:
- build
- test-pipeline:
requires:
- build
# TODO(albrow): Tests always fail on Geth right now because our fork
# is outdated. Uncomment once we have updated our Geth fork.
# - test-contracts-geth:
# requires:
# - build
- test-rest:
requires:
- build
@@ -415,6 +407,8 @@ workflows:
- static-tests-python:
requires:
- test-python
- test-python
- test-python:
requires:
- build
# skip python tox run for now, as we don't yet have multiple test environments to support.
#- test-rest-python

6
.gitattributes vendored
View File

@@ -1,7 +1,7 @@
*.sol linguist-language=Solidity
# Automatically collapse generated files in GitHub.
*.svg linguist-generated
packages/contract-artifacts/artifacts/*json linguist-generated
packages/abi-gen-wrappers/wrappers/*.ts liguist-generated
*.svg linguist-generated=true
packages/contract-artifacts/artifacts/*json linguist-generated=true
packages/abi-gen-wrappers/src/generated-wrappers/*.ts liguist-generated=true

View File

@@ -1,43 +1,43 @@
python: ['python-packages']
contracts: ['contracts']
sol-doc: ['packages/sol-doc']
sol-resolver: ['packages/sol-resolver']
contracts-gen: ['packages/contracts-gen']
sra-spec: ['packages/sra-spec']
subproviders: ['packages/subproviders']
contract-addresses: ['packages/contract-addresses']
migrations: ['packages/migrations']
web3-wrapper: ['packages/web3-wrapper']
sol-compiler: ['packages/sol-compiler']
types: ['packages/types']
instant: ['packages/instant']
abi-gen-templates: ['packages/abi-gen-templates']
abi-gen: ['packages/abi-gen']
website: ['packages/website']
sol-coverage: ['packages/sol-coverage']
sol-profiler: ['packages/sol-profiler']
sol-trace: ['packages/sol-trace']
sol-tracing-utils: ['packages/sol-tracing-utils']
utils: ['packages/utils']
tslint-config: ['packages/tslint-config']
asset-buyer: ['packages/asset-buyer']
order-watcher: ['packages/order-watcher']
react-docs: ['packages/react-docs']
order-utils: ['packages/order-utils']
react-shared: ['packages/react-shared']
assert: ['packages/assert']
base-contract: ['packages/base-contract']
typescript-typings: ['packages/typescript-typings']
@0x/sol-doc: ['packages/sol-doc']
@0x/sol-resolver: ['packages/sol-resolver']
@0x/contracts-gen: ['packages/contracts-gen']
@0x/sra-spec: ['packages/sra-spec']
@0x/subproviders: ['packages/subproviders']
@0x/contract-addresses: ['packages/contract-addresses']
@0x/migrations: ['packages/migrations']
@0x/web3-wrapper: ['packages/web3-wrapper']
@0x/sol-compiler: ['packages/sol-compiler']
@0x/types: ['packages/types']
@0x/instant: ['packages/instant']
@0x/abi-gen-templates: ['packages/abi-gen-templates']
@0x/abi-gen: ['packages/abi-gen']
@0x/website: ['packages/website']
@0x/sol-coverage: ['packages/sol-coverage']
@0x/sol-profiler: ['packages/sol-profiler']
@0x/sol-trace: ['packages/sol-trace']
@0x/sol-tracing-utils: ['packages/sol-tracing-utils']
@0x/utils: ['packages/utils']
@0x/tslint-config: ['packages/tslint-config']
@0x/asset-buyer: ['packages/asset-buyer']
@0x/order-watcher: ['packages/order-watcher']
@0x/react-docs: ['packages/react-docs']
@0x/order-utils: ['packages/order-utils']
@0x/react-shared: ['packages/react-shared']
@0x/assert: ['packages/assert']
@0x/base-contract: ['packages/base-contract']
@0x/typescript-typings: ['packages/typescript-typings']
0x.js: ['packages/0x.js']
abi-gen-wrappers: ['packages/abi-gen-wrappers']
metacoin: ['packages/metacoin']
contract-artifacts: ['packages/contract-artifacts']
dev-utils: ['packages/dev-utils']
contract-wrappers: ['packages/contract-wrappers']
json-schemas: ['packages/json-schemas']
ethereum-types: ['ethereum-types']
connect: ['packages/connect']
fill-scenarios: ['packages/fill-scenarios']
dev-tools-pages: ['packages/dev-tools-pages']
testnet-faucets: ['packages/testnet-faucets']
monorepo-scripts: ['packages/monorepo-scripts']
@0x/abi-gen-wrappers: ['packages/abi-gen-wrappers']
@0x/metacoin: ['packages/metacoin']
@0x/contract-artifacts: ['packages/contract-artifacts']
@0x/dev-utils: ['packages/dev-utils']
@0x/contract-wrappers: ['packages/contract-wrappers']
@0x/json-schemas: ['packages/json-schemas']
@0x/ethereum-types: ['ethereum-types']
@0x/connect: ['packages/connect']
@0x/fill-scenarios: ['packages/fill-scenarios']
@0x/dev-tools-pages: ['packages/dev-tools-pages']
@0x/testnet-faucets: ['packages/testnet-faucets']
@0x/monorepo-scripts: ['packages/monorepo-scripts']

9
.gitignore vendored
View File

@@ -94,11 +94,14 @@ contracts/erc721/generated-artifacts/
contracts/erc1155/generated-artifacts/
contracts/extensions/generated-artifacts/
contracts/exchange-forwarder/generated-artifacts/
contracts/dev-utils/generated-artifacts/
packages/sol-tracing-utils/test/fixtures/artifacts/
packages/metacoin/artifacts/
python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/
# generated contract wrappers
packages/abi-gen-wrappers/wrappers
packages/abi-gen-wrappers/src/generated-wrappers/
packages/python-contract-wrappers/generated/
contracts/coordinator/generated-wrappers/
contracts/exchange/generated-wrappers/
contracts/asset-proxy/generated-wrappers/
@@ -110,8 +113,12 @@ contracts/erc721/generated-wrappers/
contracts/erc1155/generated-wrappers/
contracts/extensions/generated-wrappers/
contracts/exchange-forwarder/generated-wrappers/
contracts/dev-utils/generated-wrappers/
packages/metacoin/src/contract_wrappers
# cli test output
packages/abi-gen/test-cli/output
# solc-bin in sol-compiler
packages/sol-compiler/solc_bin/

View File

@@ -22,9 +22,9 @@ lib
/contracts/extensions/generated-artifacts
/contracts/exchange-forwarder/generated-wrappers
/contracts/exchange-forwarder/generated-artifacts
/packages/abi-gen-wrappers/src/generated-wrappers
/packages/contract-artifacts/artifacts
/python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts
/contracts/dev-utils/generated-wrappers
/contracts/dev-utils/generated-artifacts
/packages/abi-gen/test-cli/output
/packages/json-schemas/schemas
/python-packages/json_schemas/src/zero_ex/json_schemas/schemas
/packages/metacoin/src/contract_wrappers

View File

@@ -11,10 +11,10 @@ packages/website/ @BMillman19 @fragosti @fabioberger @steveklebanoff
# Dev tools & setup
.circleci/ @LogvinovLeon
packages/abi-gen/ @LogvinovLeon
packages/base-contract/ @LogvinovLeon
packages/abi-gen/ @feuGeneA
packages/base-contract/ @xianny
packages/connect/ @fragosti
packages/abi-gen-templates/ @LogvinovLeon
packages/abi-gen-templates/ @feuGeneA @xianny
packages/contract-addresses/ @albrow
packages/contract-artifacts/ @albrow
packages/dev-utils/ @LogvinovLeon @fabioberger
@@ -23,6 +23,7 @@ packages/ethereum-types/ @LogvinovLeon
packages/metacoin/ @LogvinovLeon
packages/monorepo-scripts/ @fabioberger
packages/order-utils/ @fabioberger @LogvinovLeon
packages/python-contract-wrappers/ @feuGeneA
packages/sol-compiler/ @LogvinovLeon
packages/sol-coverage/ @LogvinovLeon
packages/sol-profiler/ @LogvinovLeon
@@ -36,5 +37,4 @@ python-packages/ @feuGeneA
packages/utils/ @hysz
# Protocol/smart contracts
contracts/core/test/ @albrow
contracts/ @abandeali1 @hysz

View File

@@ -2,7 +2,7 @@
<!--- Before submitting please check to see if this issue was already reported -->
<!--- Provide a general summary of the issue in the Title above -->
<!--- Prefix your issue title with the package name it relates to (e.g., `0x.js: ` or `general:`) -->
## Expected Behavior

View File

@@ -50,6 +50,7 @@ These packages are all under development. See [/contracts/README.md](/contracts/
| [`@0x/contracts-test-utils`](/contracts/test-utils) | [![npm](https://img.shields.io/npm/v/@0x/contracts-test-utils.svg)](https://www.npmjs.com/package/@0x/contracts-test-utils) | Typescript/Javascript shared utilities used for testing contracts |
| [`@0x/contracts-utils`](/contracts/utils) | [![npm](https://img.shields.io/npm/v/@0x/contracts-utils.svg)](https://www.npmjs.com/package/@0x/contracts-utils) | Generic libraries and utilities used throughout all of the contracts |
| [`@0x/contracts-coordinator`](/contracts/coordinator) | [![npm](https://img.shields.io/npm/v/@0x/contracts-coordinator.svg)](https://www.npmjs.com/package/@0x/contracts-coordinator) | A contract that allows users to execute 0x transactions with permission from a Coordinator |
| [`@0x/contracts-dev-utils`](/contracts/dev-utils) | [![npm](https://img.shields.io/npm/v/@0x/contracts-dev-utils.svg)](https://www.npmjs.com/package/@0x/contracts-dev-utils) | A contract contains utility functions for developers (such as validating many orders using a single eth_call) |
### Typescript/Javascript Packages

View File

@@ -10,3 +10,7 @@
| Forwarder | [`@0x/contracts-exchange-forwarder`](/contracts/exchange-forwarder) | [v1.0.1](https://www.npmjs.com/package/@0x/contracts-exchange-forwarder/v/1.0.1) | [@0x/contracts-exchange-forwarder@1.0.1](https://github.com/0xProject/0x-monorepo/releases/tag/@0x/contracts-exchange-forwarder@1.0.1) |
| MultiAssetProxy | [`@0x/contracts-asset-proxy`](/contracts/asset-proxy) | [v1.0.1](https://www.npmjs.com/package/@0x/contracts-asset-proxy/v/1.0.1) | [@0x/contracts-asset-proxy@1.0.1](https://github.com/0xProject/0x-monorepo/releases/tag/@0x/contracts-asset-proxy@1.0.1) |
| ZRXToken | [`@0x/contracts-erc20`](/contracts/erc20) | [v1.0.1](https://www.npmjs.com/package/@0x/contracts-erc20/v/1.0.1) | [@0x/contracts-erc20@1.0.1](https://github.com/0xProject/0x-monorepo/releases/tag/@0x/contracts-erc20@1.0.1) |
#### 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.

View File

@@ -1,4 +1,78 @@
[
{
"version": "2.2.0",
"changes": [
{
"note": "Add `LibAssetProxyIds` contract",
"pr": 1835
},
{
"note": "Updated ERC1155 Asset Proxy. Less optimization. More explicit handling of edge cases.",
"pr": 1852
},
{
"note": "Implement StaticCallProxy",
"pr": 1863
}
],
"timestamp": 1563006338
},
{
"timestamp": 1558712885,
"version": "2.1.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557961111,
"version": "2.1.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557799313,
"version": "2.1.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.1.2",
"changes": [
{
"note": "Update tests to use contract-built-in `awaitTransactionSuccessAsync`",
"pr": 1797
}
],
"timestamp": 1557507213
},
{
"version": "2.1.1",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1554997931
},
{
"version": "2.1.0",
"changes": [
{
"note": "Run Web3ProviderEngine without excess block polling",
"pr": 1695
}
],
"timestamp": 1553183790
},
{
"version": "2.0.0",
"changes": [

View File

@@ -5,6 +5,36 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.2.0 - _July 13, 2019_
* Add `LibAssetProxyIds` contract (#1835)
* Updated ERC1155 Asset Proxy. Less optimization. More explicit handling of edge cases. (#1852)
* Implement StaticCallProxy (#1863)
## v2.1.5 - _May 24, 2019_
* Dependencies updated
## v2.1.4 - _May 15, 2019_
* Dependencies updated
## v2.1.3 - _May 14, 2019_
* Dependencies updated
## v2.1.2 - _May 10, 2019_
* Update tests to use contract-built-in `awaitTransactionSuccessAsync` (#1797)
## v2.1.1 - _April 11, 2019_
* Dependencies updated
## v2.1.0 - _March 21, 2019_
* Run Web3ProviderEngine without excess block polling (#1695)
## v2.0.0 - _March 20, 2019_
* Do not reexport external dependencies (#1682)

View File

@@ -1,7 +1,7 @@
{
"artifactsDir": "./generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": true,
"useDockerisedSolc": false,
"isOfflineMode": false,
"compilerSettings": {
"evmVersion": "constantinople",
@@ -14,6 +14,7 @@
"*": {
"*": [
"abi",
"devdoc",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
@@ -28,8 +29,10 @@
"src/ERC721Proxy.sol",
"src/MixinAuthorizable.sol",
"src/MultiAssetProxy.sol",
"src/StaticCallProxy.sol",
"src/interfaces/IAssetData.sol",
"src/interfaces/IAssetProxy.sol",
"src/interfaces/IAuthorizable.sol"
"src/interfaces/IAuthorizable.sol",
"test/TestStaticCallTarget.sol"
]
}

View File

@@ -16,7 +16,7 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "./MixinAuthorizable.sol";
@@ -26,8 +26,9 @@ contract ERC1155Proxy is
{
// Id of this proxy.
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC1155Token(address,uint256[],uint256[],bytes)"));
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC1155Assets(address,uint256[],uint256[],bytes)"));
// solhint-disable-next-line payable-fallback
function ()
external
{
@@ -58,11 +59,11 @@ contract ERC1155Proxy is
// | | 100 | | 4. offset to data (*) |
// | Data | | | ids: |
// | | 132 | 32 | 1. ids Length |
// | | 164 | a | 2. ids Contents |
// | | 164 | a | 2. ids Contents |
// | | | | values: |
// | | 164 + a | 32 | 1. values Length |
// | | 196 + a | b | 2. values Contents |
// | | | | data |
// | | | | data: |
// | | 196 + a + b | 32 | 1. data Length |
// | | 228 + a + b | c | 2. data Contents |
//
@@ -80,18 +81,18 @@ contract ERC1155Proxy is
// | | 132 | | 5. offset to data (*) |
// | Data | | | ids: |
// | | 164 | 32 | 1. ids Length |
// | | 196 | a | 2. ids Contents |
// | | 196 | a | 2. ids Contents |
// | | | | values: |
// | | 196 + a | 32 | 1. values Length |
// | | 228 + a | b | 2. values Contents |
// | | | | data |
// | | | | data: |
// | | 228 + a + b | 32 | 1. data Length |
// | | 260 + a + b | c | 2. data Contents |
//
//
// (*): offset is computed from start of function parameters, so offset
// by an additional 4 bytes in the calldata.
//
//
// (**): the `Offset` column is computed assuming no calldata compression;
// offsets in the Data Area are dynamic and should be evaluated in
// real-time.
@@ -100,7 +101,7 @@ contract ERC1155Proxy is
// the Params and Data section. This will result in a larger
// offset to assetData.
//
// Note: Table #1 and Table #2 exists in Calldata. We construct Table #3 in memory.
// Note: Table #1 and Table #2 exist in Calldata. We construct Table #3 in memory.
//
//
assembly {
@@ -114,7 +115,7 @@ contract ERC1155Proxy is
// amount Amount of asset to transfer.
// bytes4(keccak256("transferFrom(bytes,address,address,uint256)")) = 0xa85e59e4
if eq(selector, 0xa85e59e400000000000000000000000000000000000000000000000000000000) {
// To lookup a value in a mapping, we load from the storage location keccak256(k, p),
// where k is the key left padded to 32 bytes and p is the storage slot
mstore(0, caller)
@@ -131,71 +132,154 @@ contract ERC1155Proxy is
}
// Construct Table #3 in memory, starting at memory offset 0.
// The algorithm below maps asset data from Table #1 and Table #2 to Table #3, while
// scaling the `values` (Table #2) by `amount` (Table #1). Once Table #3 has
// been constructed in memory, the destination erc1155 contract is called using this
// as its calldata. This process is divided into four steps, below.
// The algorithm below maps calldata (Table #1) and assetData (Table #2) to memory (Table #3).
// Once Table #3 ha been constructed in memory, the destination erc1155 contract is called using this
// as its calldata. This process is divided into three steps, below.
////////// STEP 1/3 - Map calldata to memory (Table #1 -> Table #3) //////////
// Store the safeBatchTransferFrom function selector, which is computed using:
// bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)"))
mstore(0, 0x2eb2c2d600000000000000000000000000000000000000000000000000000000)
// Copy `from` and `to` fields from calldata (Table #1) into memory (Table #3)
calldatacopy(
4, // aligned such that `from` and `to` are at the correct location for Table #3
36, // beginning of `from` field from Table #1
64 // 32 bytes for `from` + 32 bytes for `to` field
)
////////// STEP 2/3 - Map assetData to memory (Table #2 -> Table #3) //////////
////////// STEP 1/4 //////////
// Map relevant fields from assetData (Table #2) into memory (Table #3)
// The Contents column of Table #2 is the same as Table #3,
// beginning from parameter 3 - `offset to ids (*)`
// The offsets in these rows are offset by 32 bytes in Table #3.
// Strategy:
// 1. Copy the assetData into memory at offset 32
// 2. Increment by 32 the offsets to `ids`, `values`, and `data`
// The `values` from assetData (Table #2) are multiplied by `amount` (Table #1)
// when they are copied into memory.
// Load offset to `assetData`
let assetDataOffset := calldataload(4)
let assetDataOffset := add(calldataload(4), 4)
// Load length in bytes of `assetData`, computed by:
// 4 (function selector)
// + assetDataOffset
let assetDataLength := calldataload(add(4, assetDataOffset))
// Load length in bytes of `assetData`
let assetDataLength := calldataload(assetDataOffset)
// This corresponds to the beginning of the Data Area for Table #3.
// Computed by:
// 4 (function selector)
// + assetDataOffset
// + 32 (length of assetData)
calldatacopy(
32, // aligned such that "offset to ids" is at the correct location for Table #3
add(36, assetDataOffset), // beginning of asset data contents
assetDataLength // length of asset data
)
// Assert that the length of asset data:
// 1. Must be at least 132 bytes (Table #2)
// 2. Must be a multiple of 32 (excluding the 4-byte selector)
if or(lt(assetDataLength, 132), mod(sub(assetDataLength, 4), 32)) {
// Revert with `Error("INVALID_ASSET_DATA_LENGTH")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000019494e56414c49445f41535345545f444154415f4c454e475448000000)
mstore(96, 0)
revert(0, 100)
}
// Increment by 32 the offsets to `ids`, `values`, and `data`
mstore(68, add(mload(68), 32))
mstore(100, add(mload(100), 32))
mstore(132, add(mload(132), 32))
// End of asset data in calldata
// +32 for length field
let assetDataEnd := add(assetDataOffset, add(assetDataLength, 32))
if gt(assetDataEnd, calldatasize()) {
// Revert with `Error("INVALID_ASSET_DATA_END")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000016494e56414c49445f41535345545f444154415f454e44000000000000)
mstore(96, 0)
revert(0, 100)
}
// Record the address of the destination erc1155 asset for later.
let assetAddress := and(
mload(36),
0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
)
// Load offset to parameters section in asset data
let paramsInAssetDataOffset := add(assetDataOffset, 36)
////////// STEP 2/4 //////////
// Offset of end of Data Area in memory.
// This value will grow as we construct Table #3.
let dataAreaEndOffset := 164
// Load amount by which to scale values
let amount := calldataload(100)
let valuesOffset := add(mload(100), 4) // add 4 for calldata offset
let valuesLengthInBytes := mul(
mload(valuesOffset),
32
// Store pointer to `ids` (Table #3)
// Subtract 4 for `safeBatchTransferFrom` selector
mstore(68, sub(dataAreaEndOffset, 4))
// Ensure length of `ids` does not overflow
let idsOffset := add(paramsInAssetDataOffset, calldataload(add(assetDataOffset, 68)))
let idsLength := calldataload(idsOffset)
let idsLengthInBytes := mul(idsLength, 32)
if sub(div(idsLengthInBytes, 32), idsLength) {
// Revert with `Error("UINT256_OVERFLOW")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x0000001055494e543235365f4f564552464c4f57000000000000000000000000)
mstore(96, 0)
revert(0, 100)
}
// Ensure `ids` does not resolve to outside of `assetData`
let idsBegin := add(idsOffset, 32)
let idsEnd := add(idsBegin, idsLengthInBytes)
if gt(idsEnd, assetDataEnd) {
// Revert with `Error("INVALID_IDS_OFFSET")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000012494e56414c49445f4944535f4f464653455400000000000000000000)
mstore(96, 0)
revert(0, 100)
}
// Copy `ids` from `assetData` (Table #2) to memory (Table #3)
calldatacopy(
dataAreaEndOffset,
idsOffset,
add(idsLengthInBytes, 32)
)
dataAreaEndOffset := add(dataAreaEndOffset, add(idsLengthInBytes, 32))
// Store pointer to `values` (Table #3)
// Subtract 4 for `safeBatchTrasferFrom` selector
mstore(100, sub(dataAreaEndOffset, 4))
// Ensure length of `values` does not overflow
let valuesOffset := add(paramsInAssetDataOffset, calldataload(add(assetDataOffset, 100)))
let valuesLength := calldataload(valuesOffset)
let valuesLengthInBytes := mul(valuesLength, 32)
if sub(div(valuesLengthInBytes, 32), valuesLength) {
// Revert with `Error("UINT256_OVERFLOW")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x0000001055494e543235365f4f564552464c4f57000000000000000000000000)
mstore(96, 0)
revert(0, 100)
}
// Ensure `values` does not resolve to outside of `assetData`
let valuesBegin := add(valuesOffset, 32)
let valuesEnd := add(valuesBegin, valuesLengthInBytes)
for { let tokenValueOffset := valuesBegin }
lt(tokenValueOffset, valuesEnd)
{ tokenValueOffset := add(tokenValueOffset, 32) }
if gt(valuesEnd, assetDataEnd) {
// Revert with `Error("INVALID_VALUES_OFFSET")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000015494e56414c49445f56414c5545535f4f464653455400000000000000)
mstore(96, 0)
revert(0, 100)
}
// Store length of `values`
mstore(dataAreaEndOffset, valuesLength)
dataAreaEndOffset := add(dataAreaEndOffset, 32)
// Scale and store elements of `values`
for { let currentValueOffset := valuesBegin }
lt(currentValueOffset, valuesEnd)
{ currentValueOffset := add(currentValueOffset, 32) }
{
// Load token value and generate scaled value
let tokenValue := mload(tokenValueOffset)
let scaledTokenValue := mul(tokenValue, amount)
// Load value and generate scaled value
let currentValue := calldataload(currentValueOffset)
let currentValueScaled := mul(currentValue, amount)
// Revert if `amount` != 0 and multiplication resulted in an overflow
if iszero(or(
iszero(amount),
eq(div(scaledTokenValue, amount), tokenValue)
eq(div(currentValueScaled, amount), currentValue)
)) {
// Revert with `Error("UINT256_OVERFLOW")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
@@ -205,33 +289,57 @@ contract ERC1155Proxy is
revert(0, 100)
}
// There was no overflow, update `tokenValue` with its scaled counterpart
mstore(tokenValueOffset, scaledTokenValue)
// There was no overflow, store the scaled token value
mstore(dataAreaEndOffset, currentValueScaled)
dataAreaEndOffset := add(dataAreaEndOffset, 32)
}
////////// STEP 3/4 //////////
// Store the safeBatchTransferFrom function selector,
// and copy `from`/`to` fields from Table #1 to Table #3.
// Store pointer to `data` (Table #3)
// Subtract 4 for `safeBatchTrasferFrom` selector
mstore(132, sub(dataAreaEndOffset, 4))
// The function selector is computed using:
// bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)"))
mstore(0, 0x2eb2c2d600000000000000000000000000000000000000000000000000000000)
// Ensure `data` does not resolve to outside of `assetData`
let dataOffset := add(paramsInAssetDataOffset, calldataload(add(assetDataOffset, 132)))
let dataLengthInBytes := calldataload(dataOffset)
let dataBegin := add(dataOffset, 32)
let dataEnd := add(dataBegin, dataLengthInBytes)
if gt(dataEnd, assetDataEnd) {
// Revert with `Error("INVALID_DATA_OFFSET")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000013494e56414c49445f444154415f4f4646534554000000000000000000)
mstore(96, 0)
revert(0, 100)
}
// Copy `from` and `to` fields from Table #1 to Table #3
// Copy `data` from `assetData` (Table #2) to memory (Table #3)
calldatacopy(
4, // aligned such that `from` and `to` are at the correct location for Table #3
36, // beginning of `from` field from Table #1
64 // 32 bytes for `from` + 32 bytes for `to` field
dataAreaEndOffset,
dataOffset,
add(dataLengthInBytes, 32)
)
// Update the end of data offset to be word-aligned
let dataLengthInWords := div(add(dataLengthInBytes, 31), 32)
let dataLengthInBytesWordAligned := mul(dataLengthInWords, 32)
dataAreaEndOffset := add(dataAreaEndOffset, add(dataLengthInBytesWordAligned, 32))
////////// STEP 3/3 - Execute Transfer //////////
// Load the address of the destination erc1155 contract from asset data (Table #2)
// +32 bytes for assetData Length
// +4 bytes for assetProxyId
let assetAddress := and(
calldataload(add(assetDataOffset, 36)),
0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
)
////////// STEP 4/4 //////////
// Call into the destination erc1155 contract using as calldata Table #3 (constructed in-memory above)
let success := call(
gas, // forward all gas
assetAddress, // call address of erc1155 asset
0, // don't send any ETH
0, // pointer to start of input
add(assetDataLength, 32), // length of input (Table #3) is 32 bytes longer than `assetData` (Table #2)
dataAreaEndOffset, // length of input is the end of the Data Area (Table #3)
0, // write output over memory that won't be reused
0 // don't copy output to memory
)
@@ -245,7 +353,7 @@ contract ERC1155Proxy is
)
revert(0, returndatasize())
}
// Return if call was successful
return(0, 0)
}

View File

@@ -0,0 +1,207 @@
/*
Copyright 2018 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;
contract StaticCallProxy {
// Id of this proxy.
bytes4 constant internal PROXY_ID = bytes4(keccak256("StaticCall(address,bytes,bytes32)"));
// solhint-disable-next-line payable-fallback
function ()
external
{
assembly {
// The first 4 bytes of calldata holds the function selector
let selector := and(calldataload(0), 0xffffffff00000000000000000000000000000000000000000000000000000000)
// `transferFrom` will be called with the following parameters:
// assetData Encoded byte array.
// from Address to transfer asset from.
// to Address to transfer asset to.
// amount Amount of asset to transfer.
// bytes4(keccak256("transferFrom(bytes,address,address,uint256)")) = 0xa85e59e4
if eq(selector, 0xa85e59e400000000000000000000000000000000000000000000000000000000) {
// `transferFrom`.
// The function is marked `external`, so no abi decoding is done for
// us. Instead, we expect the `calldata` memory to contain the
// following:
//
// | Area | Offset | Length | Contents |
// |----------|--------|---------|-------------------------------------|
// | Header | 0 | 4 | function selector |
// | Params | | 4 * 32 | function parameters: |
// | | 4 | | 1. offset to assetData (*) |
// | | 36 | | 2. from |
// | | 68 | | 3. to |
// | | 100 | | 4. amount |
// | Data | | | assetData: |
// | | 132 | 32 | assetData Length |
// | | 164 | ** | assetData Contents |
//
// (*): offset is computed from start of function parameters, so offset
// by an additional 4 bytes in the calldata.
//
// (**): see table below to compute length of assetData Contents
// (***): Note that the `from`, `to`, and `amount` params in calldata are ignored in this function.
//
// WARNING: The ABIv2 specification allows additional padding between
// the Params and Data section. This will result in a larger
// offset to assetData.
// Load offset to `assetData`
let assetDataOffset := add(calldataload(4), 4)
// Validate length of `assetData`
let assetDataLen := calldataload(assetDataOffset)
if or(lt(assetDataLen, 100), mod(sub(assetDataLen, 4), 32)) {
// Revert with `Error("INVALID_ASSET_DATA_LENGTH")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000019494e56414c49445f41535345545f444154415f4c454e475448000000)
mstore(96, 0)
revert(0, 100)
}
// Ensure that `assetData` ends inside of calldata
let assetDataEnd := add(assetDataOffset, add(assetDataLen, 32))
if gt(assetDataEnd, calldatasize()) {
// Revert with `Error("INVALID_ASSET_DATA_END")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000016494e56414c49445f41535345545f444154415f454e44000000000000)
mstore(96, 0)
revert(0, 100)
}
// Asset data is encoded as follows:
// | Area | Offset | Length | Contents |
// |----------|-------------|---------|--------------------------------------|
// | Header | 0 | 4 | assetProxyId |
// | Params | | 4 * 32 | function parameters: |
// | | 4 | | 1. address of callTarget |
// | | 36 | | 2. offset to staticCallData (*) |
// | | 68 | | 3. expected 32 byte hash of output |
// | Data | | | staticCallData: |
// | | 100 | 32 | 1. staticCallData Length |
// | | 132 | a | 2. staticCallData Contents |
// In order to find the offset to `staticCallData`, we must add:
// assetDataOffset
// + 32 (assetData len)
// + 4 (proxyId)
// + 32 (callTarget)
let paramsInAssetDataOffset := add(assetDataOffset, 36)
let staticCallDataOffset := add(paramsInAssetDataOffset, calldataload(add(assetDataOffset, 68)))
// Load length of `staticCallData`
let staticCallDataLen := calldataload(staticCallDataOffset)
// Ensure `staticCallData` does not begin to outside of `assetData`
let staticCallDataBegin := add(staticCallDataOffset, 32)
let staticCallDataEnd := add(staticCallDataBegin, staticCallDataLen)
if gt(staticCallDataEnd, assetDataEnd) {
// Revert with `Error("INVALID_STATIC_CALL_DATA_OFFSET")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x0000001f494e56414c49445f5354415449435f43414c4c5f444154415f4f4646)
mstore(96, 0x5345540000000000000000000000000000000000000000000000000000000000)
revert(0, 100)
}
// Copy `staticCallData` into memory
calldatacopy(
0, // memory can be safely overwritten from beginning
staticCallDataBegin, // start of `staticCallData`
staticCallDataLen // copy the entire `staticCallData`
)
// In order to find the offset to `callTarget`, we must add:
// assetDataOffset
// + 32 (assetData len)
// + 4 (proxyId)
let callTarget := and(
calldataload(add(assetDataOffset, 36)),
0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
)
// Perform `callTarget.staticcall(staticCallData)`
let success := staticcall(
gas, // forward all gas
callTarget, // call address `callTarget`
0, // pointer to start of input
staticCallDataLen, // length of input
0, // start of memory can be safely overwritten
0 // don't copy output to memory
)
// Copy entire output to start of memory
let outputLen := returndatasize()
returndatacopy(
0, // copy to memory at 0
0, // copy from return data at 0
outputLen // copy all return data
)
// Revert with reason given by `callTarget` if staticcall is unsuccessful
if iszero(success) {
revert(0, outputLen)
}
// Calculate hash of output
let callResultHash := keccak256(0, outputLen)
// In order to find the offset to `expectedCallResultHash`, we must add:
// assetDataOffset
// + 32 (assetData len)
// + 4 (proxyId)
// + 32 (callTarget)
// + 32 (staticCallDataOffset)
let expectedResultHash := calldataload(add(assetDataOffset, 100))
if sub(callResultHash, expectedResultHash) {
// Revert with `Error("UNEXPECTED_STATIC_CALL_RESULT")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x0000001d554e45585045435445445f5354415449435f43414c4c5f524553554c)
mstore(96, 0x5400000000000000000000000000000000000000000000000000000000000000)
revert(0, 100)
}
// Return if output matched expected output
return(0, 0)
}
// Revert if undefined function is called
revert(0, 0)
}
}
/// @dev Gets the proxy id associated with the proxy address.
/// @return Proxy id.
function getProxyId()
external
pure
returns (bytes4)
{
return PROXY_ID;
}
}

View File

@@ -26,19 +26,33 @@ pragma experimental ABIEncoderV2;
// This argument is ABI encoded as one of the methods of this interface.
interface IAssetData {
function ERC20Token(address tokenContract)
function ERC20Token(address tokenAddress)
external;
function ERC721Token(
address tokenContract,
address tokenAddress,
uint256 tokenId
)
external;
function ERC1155Assets(
address tokenAddress,
uint256[] calldata tokenIds,
uint256[] calldata tokenValues,
bytes calldata callbackData
)
external;
function MultiAsset(
uint256[] calldata amounts,
bytes[] calldata nestedAssetData
)
external;
function StaticCall(
address callTarget,
bytes calldata staticCallData,
bytes32 callResultHash
)
external;
}

View File

@@ -0,0 +1,40 @@
/*
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.5;
contract LibAssetProxyIds {
// AssetProxy Ids are equiavalent the first 4 bytes of the keccak256 hash of the function signature assigned to each AssetProxy.
// ERC20Token(address)
bytes4 constant public ERC20_PROXY_ID = 0xf47261b0;
// ERC721Token(address,uint256)
bytes4 constant public ERC721_PROXY_ID = 0x02571792;
// ERC1155Assets(address,uint256[],uint256[],bytes)
bytes4 constant public ERC1155_PROXY_ID = 0xa7cb5fb7;
// MultiAsset(uint256[],bytes[])
bytes4 constant public MULTI_ASSET_PROXY_ID = 0x94cfcdd7;
// StaticCall(address,bytes,bytes32)
bytes4 constant public STATIC_CALL_PROXY_ID = 0xc339d10a;
}

View File

@@ -0,0 +1,82 @@
/*
Copyright 2018 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;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
contract TestStaticCallTarget {
using LibBytes for bytes;
uint256 internal _state;
function updateState()
external
{
_state++;
}
function assertEvenNumber(uint256 target)
external
pure
{
require(
target % 2 == 0,
"TARGET_NOT_EVEN"
);
}
function isOddNumber(uint256 target)
external
pure
returns (bool isOdd)
{
isOdd = target % 2 == 1;
return isOdd;
}
function noInputFunction()
external
pure
{
assert(msg.data.length == 4 && msg.data.readBytes4(0) == bytes4(keccak256("noInputFunction()")));
}
function dynamicInputFunction(bytes calldata a)
external
pure
{
bytes memory abiEncodedData = abi.encodeWithSignature("dynamicInputFunction(bytes)", a);
assert(msg.data.equals(abiEncodedData));
}
function returnComplexType(uint256 a, uint256 b)
external
view
returns (bytes memory result)
{
result = abi.encodePacked(
address(this),
a,
b
);
return result;
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-asset-proxy",
"version": "2.0.0",
"version": "2.2.0",
"engines": {
"node": ">=6.12"
},
@@ -24,6 +24,7 @@
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html",
@@ -33,7 +34,7 @@
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
},
"config": {
"abis": "./generated-artifacts/@(ERC1155Proxy|ERC20Proxy|ERC721Proxy|IAssetData|IAssetProxy|IAuthorizable|MixinAuthorizable|MultiAssetProxy).json",
"abis": "./generated-artifacts/@(ERC1155Proxy|ERC20Proxy|ERC721Proxy|IAssetData|IAssetProxy|IAuthorizable|MixinAuthorizable|MultiAssetProxy|StaticCallProxy|TestStaticCallTarget).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
@@ -46,12 +47,12 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
"devDependencies": {
"@0x/abi-gen": "^2.0.7",
"@0x/contracts-gen": "^1.0.6",
"@0x/contracts-test-utils": "^3.1.0",
"@0x/dev-utils": "^2.1.4",
"@0x/sol-compiler": "^3.1.4",
"@0x/tslint-config": "^3.0.0",
"@0x/abi-gen": "^2.1.0",
"@0x/contracts-gen": "^1.0.10",
"@0x/contracts-test-utils": "^3.1.8",
"@0x/dev-utils": "^2.2.4",
"@0x/sol-compiler": "^3.1.9",
"@0x/tslint-config": "^3.0.1",
"@types/lodash": "4.14.104",
"@types/node": "*",
"chai": "^4.0.1",
@@ -67,17 +68,18 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.0.3",
"@0x/contracts-erc1155": "^1.0.1",
"@0x/contracts-erc20": "^2.0.0",
"@0x/contracts-erc721": "^2.0.0",
"@0x/contracts-utils": "^3.0.0",
"@0x/order-utils": "^7.1.0",
"@0x/types": "^2.2.0",
"@0x/typescript-typings": "^4.2.0",
"@0x/utils": "^4.2.3",
"@0x/web3-wrapper": "^6.0.3",
"ethereum-types": "^2.1.1",
"@0x/base-contract": "^5.1.1",
"@0x/contracts-erc1155": "^1.1.7",
"@0x/contracts-erc20": "^2.2.6",
"@0x/contracts-erc721": "^2.1.7",
"@0x/contracts-utils": "^3.1.7",
"@0x/order-utils": "^8.2.0",
"@0x/types": "^2.4.0",
"@0x/typescript-typings": "^4.2.3",
"@0x/utils": "^4.4.0",
"@0x/web3-wrapper": "^6.0.7",
"ethereum-types": "^2.1.3",
"ethereumjs-util": "^5.1.1",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -13,13 +13,17 @@ import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json';
import * as IAuthorizable from '../generated-artifacts/IAuthorizable.json';
import * as MixinAuthorizable from '../generated-artifacts/MixinAuthorizable.json';
import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json';
import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json';
import * as TestStaticCallTarget from '../generated-artifacts/TestStaticCallTarget.json';
export const artifacts = {
ERC1155Proxy: ERC1155Proxy as ContractArtifact,
ERC20Proxy: ERC20Proxy as ContractArtifact,
ERC721Proxy: ERC721Proxy as ContractArtifact,
ERC1155Proxy: ERC1155Proxy as ContractArtifact,
MixinAuthorizable: MixinAuthorizable as ContractArtifact,
MultiAssetProxy: MultiAssetProxy as ContractArtifact,
StaticCallProxy: StaticCallProxy as ContractArtifact,
IAssetData: IAssetData as ContractArtifact,
IAssetProxy: IAssetProxy as ContractArtifact,
IAuthorizable: IAuthorizable as ContractArtifact,
TestStaticCallTarget: TestStaticCallTarget as ContractArtifact,
};

View File

@@ -11,3 +11,5 @@ export * from '../generated-wrappers/i_asset_proxy';
export * from '../generated-wrappers/i_authorizable';
export * from '../generated-wrappers/mixin_authorizable';
export * from '../generated-wrappers/multi_asset_proxy';
export * from '../generated-wrappers/static_call_proxy';
export * from '../generated-wrappers/test_static_call_target';

View File

@@ -53,16 +53,18 @@ describe('Authorizable', () => {
);
});
it('should allow owner to add an authorized address', async () => {
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const isAuthorized = await authorizable.authorized.callAsync(address);
expect(isAuthorized).to.be.true();
});
it('should throw if owner attempts to authorize a duplicate address', async () => {
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
return expectTransactionFailedAsync(
@@ -74,8 +76,9 @@ describe('Authorizable', () => {
describe('removeAuthorizedAddress', () => {
it('should throw if not called by owner', async () => {
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
return expectTransactionFailedAsync(
@@ -87,14 +90,14 @@ describe('Authorizable', () => {
});
it('should allow owner to remove an authorized address', async () => {
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
from: owner,
}),
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const isAuthorized = await authorizable.authorized.callAsync(address);
@@ -113,8 +116,9 @@ describe('Authorizable', () => {
describe('removeAuthorizedAddressAtIndex', () => {
it('should throw if not called by owner', async () => {
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const index = new BigNumber(0);
@@ -126,8 +130,9 @@ describe('Authorizable', () => {
);
});
it('should throw if index is >= authorities.length', async () => {
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const index = new BigNumber(1);
@@ -150,12 +155,14 @@ describe('Authorizable', () => {
it('should throw if address at index does not match target', async () => {
const address1 = address;
const address2 = notOwner;
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address1, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address1,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address2, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address2,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const address1Index = new BigNumber(0);
@@ -167,15 +174,16 @@ describe('Authorizable', () => {
);
});
it('should allow owner to remove an authorized address', async () => {
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const index = new BigNumber(0);
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
from: owner,
}),
await authorizable.removeAuthorizedAddressAtIndex.awaitTransactionSuccessAsync(
address,
index,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const isAuthorized = await authorizable.authorized.callAsync(address);
@@ -187,20 +195,17 @@ describe('Authorizable', () => {
it('should return all authorized addresses', async () => {
const initial = await authorizable.getAuthorizedAddresses.callAsync();
expect(initial).to.have.length(0);
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, {
from: owner,
}),
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const afterAdd = await authorizable.getAuthorizedAddresses.callAsync();
expect(afterAdd).to.have.length(1);
expect(afterAdd).to.include(address);
await web3Wrapper.awaitTransactionSuccessAsync(
await authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
from: owner,
}),
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const afterRemove = await authorizable.getAuthorizedAddresses.callAsync();

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,10 @@
import { env, EnvVars } from '@0x/dev-utils';
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
import { providerUtils } from '@0x/utils';
before('start web3 provider', () => {
provider.start();
providerUtils.startProviderEngine(provider);
});
after('generate coverage report', async () => {
if (env.parseBoolean(EnvVars.SolidityCoverage)) {

View File

@@ -44,16 +44,8 @@ import {
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const assetProxyInterface = new IAssetProxyContract(
artifacts.IAssetProxy.compilerOutput.abi,
constants.NULL_ADDRESS,
provider,
);
const assetDataInterface = new IAssetDataContract(
artifacts.IAssetData.compilerOutput.abi,
constants.NULL_ADDRESS,
provider,
);
const assetProxyInterface = new IAssetProxyContract(constants.NULL_ADDRESS, provider);
const assetDataInterface = new IAssetDataContract(constants.NULL_ADDRESS, provider);
// tslint:disable:no-unnecessary-type-assertion
describe('Asset Transfer Proxies', () => {
@@ -111,72 +103,62 @@ describe('Asset Transfer Proxies', () => {
);
// Configure ERC20Proxy
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
from: owner,
}),
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
from: owner,
}),
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
multiAssetProxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
// Configure ERC721Proxy
await web3Wrapper.awaitTransactionSuccessAsync(
await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
from: owner,
}),
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
from: owner,
}),
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
multiAssetProxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
// Configure ERC115Proxy
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
await web3Wrapper.awaitTransactionSuccessAsync(
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
from: owner,
}),
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
from: owner,
}),
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
multiAssetProxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
// Configure MultiAssetProxy
await web3Wrapper.awaitTransactionSuccessAsync(
await multiAssetProxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
from: owner,
}),
await multiAssetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, {
from: owner,
}),
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
erc20Proxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc721Proxy.address, {
from: owner,
}),
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
erc721Proxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc1155Proxy.address, {
from: owner,
}),
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
erc1155Proxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
@@ -206,31 +188,32 @@ describe('Asset Transfer Proxies', () => {
);
await erc20Wrapper.setBalancesAndAllowancesAsync();
await web3Wrapper.awaitTransactionSuccessAsync(
await noReturnErc20Token.setBalance.sendTransactionAsync(fromAddress, constants.INITIAL_ERC20_BALANCE),
await noReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
fromAddress,
constants.INITIAL_ERC20_BALANCE,
{
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await noReturnErc20Token.approve.sendTransactionAsync(
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: fromAddress },
),
await noReturnErc20Token.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await multipleReturnErc20Token.setBalance.sendTransactionAsync(
fromAddress,
constants.INITIAL_ERC20_BALANCE,
),
await multipleReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
fromAddress,
constants.INITIAL_ERC20_BALANCE,
{
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await multipleReturnErc20Token.approve.sendTransactionAsync(
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: fromAddress },
),
await multipleReturnErc20Token.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
@@ -419,10 +402,10 @@ describe('Asset Transfer Proxies', () => {
toAddress,
amount,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, allowance, {
from: fromAddress,
}),
await erc20TokenA.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
allowance,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const erc20Balances = await erc20Wrapper.getBalancesAsync();
@@ -451,10 +434,10 @@ describe('Asset Transfer Proxies', () => {
toAddress,
amount,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await noReturnErc20Token.approve.sendTransactionAsync(erc20Proxy.address, allowance, {
from: fromAddress,
}),
await noReturnErc20Token.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
allowance,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
const initialFromBalance = await noReturnErc20Token.balanceOf.callAsync(fromAddress);
@@ -692,10 +675,10 @@ describe('Asset Transfer Proxies', () => {
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
expect(ownerFromAsset).to.be.equal(fromAddress);
// Remove transfer approval for fromAddress.
await web3Wrapper.awaitTransactionSuccessAsync(
await erc721TokenA.approve.sendTransactionAsync(constants.NULL_ADDRESS, erc721AFromTokenId, {
from: fromAddress,
}),
await erc721TokenA.approve.awaitTransactionSuccessAsync(
constants.NULL_ADDRESS,
erc721AFromTokenId,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
// Perform a transfer; expect this to fail.

View File

@@ -0,0 +1,250 @@
import {
chaiSetup,
constants,
expectTransactionFailedAsync,
expectTransactionFailedWithoutReasonAsync,
provider,
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { assetDataUtils } from '@0x/order-utils';
import { AssetProxyId, RevertReason } from '@0x/types';
import { AbiEncoder, BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as ethUtil from 'ethereumjs-util';
import { artifacts, IAssetProxyContract, StaticCallProxyContract, TestStaticCallTargetContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('StaticCallProxy', () => {
const amount = constants.ZERO_AMOUNT;
let fromAddress: string;
let toAddress: string;
let staticCallProxy: IAssetProxyContract;
let staticCallTarget: TestStaticCallTargetContract;
before(async () => {
await blockchainLifecycle.startAsync();
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync();
[fromAddress, toAddress] = accounts.slice(0, 2);
const staticCallProxyWithoutTransferFrom = await StaticCallProxyContract.deployFrom0xArtifactAsync(
artifacts.StaticCallProxy,
provider,
txDefaults,
);
staticCallProxy = new IAssetProxyContract(staticCallProxyWithoutTransferFrom.address, provider, txDefaults);
staticCallTarget = await TestStaticCallTargetContract.deployFrom0xArtifactAsync(
artifacts.TestStaticCallTarget,
provider,
txDefaults,
);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
describe('general', () => {
it('should revert if undefined function is called', async () => {
const undefinedSelector = '0x01020304';
await expectTransactionFailedWithoutReasonAsync(
web3Wrapper.sendTransactionAsync({
from: fromAddress,
to: staticCallProxy.address,
value: constants.ZERO_AMOUNT,
data: undefinedSelector,
}),
);
});
it('should have an id of 0xc339d10a', async () => {
const proxyId = await staticCallProxy.getProxyId.callAsync();
const expectedProxyId = AssetProxyId.StaticCall;
expect(proxyId).to.equal(expectedProxyId);
});
});
describe('transferFrom', () => {
it('should revert if assetData lies outside the bounds of calldata', async () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const txData = staticCallProxy.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
toAddress,
amount,
);
const offsetToAssetData = '0000000000000000000000000000000000000000000000000000000000000080';
const txDataEndBuffer = ethUtil.toBuffer((txData.length - 2) / 2 - 4);
const paddedTxDataEndBuffer = ethUtil.setLengthLeft(txDataEndBuffer, 32);
const invalidOffsetToAssetData = ethUtil.bufferToHex(paddedTxDataEndBuffer).slice(2);
const newAssetData = '0000000000000000000000000000000000000000000000000000000000000304';
const badTxData = `${txData.replace(offsetToAssetData, invalidOffsetToAssetData)}${newAssetData}`;
await expectTransactionFailedAsync(
web3Wrapper.sendTransactionAsync({
to: staticCallProxy.address,
from: fromAddress,
data: badTxData,
}),
RevertReason.InvalidAssetDataEnd,
);
});
it('should revert if the length of assetData, excluding the proxyId, is not a multiple of 32', async () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = `${assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
)}01`;
await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
RevertReason.InvalidAssetDataLength,
);
});
it('should revert if the length of assetData is less than 100 bytes', async () => {
const staticCallData = constants.NULL_BYTES;
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.slice(0, -128);
const assetDataByteLen = (assetData.length - 2) / 2;
expect((assetDataByteLen - 4) % 32).to.equal(0);
await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
RevertReason.InvalidAssetDataLength,
);
});
it('should revert if the offset to `staticCallData` points to outside of assetData', async () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const offsetToStaticCallData = '0000000000000000000000000000000000000000000000000000000000000060';
const assetDataEndBuffer = ethUtil.toBuffer((assetData.length - 2) / 2 - 4);
const paddedAssetDataEndBuffer = ethUtil.setLengthLeft(assetDataEndBuffer, 32);
const invalidOffsetToStaticCallData = ethUtil.bufferToHex(paddedAssetDataEndBuffer).slice(2);
const newStaticCallData = '0000000000000000000000000000000000000000000000000000000000000304';
const badAssetData = `${assetData.replace(
offsetToStaticCallData,
invalidOffsetToStaticCallData,
)}${newStaticCallData}`;
await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(badAssetData, fromAddress, toAddress, amount),
RevertReason.InvalidStaticCallDataOffset,
);
});
it('should revert if the callTarget attempts to write to state', async () => {
const staticCallData = staticCallTarget.updateState.getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await expectTransactionFailedWithoutReasonAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
);
});
it('should revert with data provided by the callTarget if the staticcall reverts', async () => {
const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1));
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
RevertReason.TargetNotEven,
);
});
it('should revert if the hash of the output is different than expected expected', async () => {
const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0));
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await expectTransactionFailedAsync(
staticCallProxy.transferFrom.sendTransactionAsync(assetData, fromAddress, toAddress, amount),
RevertReason.UnexpectedStaticCallResult,
);
});
it('should be successful if a function call with no inputs is successful', async () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
});
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 trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
});
it('should be successful if a function with one dynamic input is successful', async () => {
const dynamicInput = '0x0102030405060708';
const staticCallData = staticCallTarget.dynamicInputFunction.getABIEncodedTransactionData(dynamicInput);
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
});
it('should be successful if a function call returns a complex type', async () => {
const a = new BigNumber(1);
const b = new BigNumber(2);
const staticCallData = staticCallTarget.returnComplexType.getABIEncodedTransactionData(a, b);
const abiEncoder = new AbiEncoder.DynamicBytes({
name: '',
type: 'bytes',
});
const aHex = '0000000000000000000000000000000000000000000000000000000000000001';
const bHex = '0000000000000000000000000000000000000000000000000000000000000002';
const expectedResults = `${staticCallTarget.address}${aHex}${bHex}`;
const offset = '0000000000000000000000000000000000000000000000000000000000000020';
const encodedExpectedResultWithOffset = `0x${offset}${abiEncoder.encode(expectedResults).slice(2)}`;
const expectedResultHash = ethUtil.bufferToHex(
ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)),
);
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount);
});
});
});

View File

@@ -36,11 +36,7 @@ export class ERC1155ProxyWrapper {
const allArtifacts = _.merge(artifacts, erc1155Artifacts);
this._logDecoder = new LogDecoder(this._web3Wrapper, allArtifacts);
this._dummyTokenWrappers = [];
this._assetProxyInterface = new IAssetProxyContract(
artifacts.IAssetProxy.compilerOutput.abi,
constants.NULL_ADDRESS,
provider,
);
this._assetProxyInterface = new IAssetProxyContract(constants.NULL_ADDRESS, provider);
this._tokenOwnerAddresses = tokenOwnerAddresses;
this._contractOwnerAddress = contractOwnerAddress;
this._fungibleTokenIds = [];
@@ -84,6 +80,66 @@ export class ERC1155ProxyWrapper {
this._validateProxyContractExistsOrThrow();
return this._proxyIdIfExists as string;
}
/**
* @dev generates abi-encoded tx data for transferring erc1155 fungible/non-fungible tokens.
* @param from source address
* @param to destination address
* @param contractAddress address of erc155 contract
* @param tokensToTransfer array of erc1155 tokens to transfer
* @param valuesToTransfer array of corresponding values for each erc1155 token to transfer
* @param valueMultiplier each value in `valuesToTransfer` is multiplied by this
* @param receiverCallbackData callback data if `to` is a contract
* @param authorizedSender sender of `transferFrom` transaction
* @param extraData extra data to append to `transferFrom` transaction. Optional.
* @return abi encoded tx data.
*/
public getTransferFromAbiEncodedTxData(
from: string,
to: string,
contractAddress: string,
tokensToTransfer: BigNumber[],
valuesToTransfer: BigNumber[],
valueMultiplier: BigNumber,
receiverCallbackData: string,
authorizedSender: string,
assetData_?: string,
): string {
this._validateProxyContractExistsOrThrow();
const assetData =
assetData_ === undefined
? assetDataUtils.encodeERC1155AssetData(
contractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
: assetData_;
const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
from,
to,
valueMultiplier,
);
return data;
}
/**
* @dev transfers erc1155 fungible/non-fungible tokens.
* @param txData: abi-encoded tx data
* @param authorizedSender sender of `transferFrom` transaction
*/
public async transferFromRawAsync(
txData: string,
authorizedSender: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const txHash = await this._web3Wrapper.sendTransactionAsync({
to: (this._proxyContract as ERC1155ProxyContract).address,
data: txData,
from: authorizedSender,
gas: 300000,
});
const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
return txReceipt;
}
/**
* @dev transfers erc1155 fungible/non-fungible tokens.
* @param from source address
@@ -106,20 +162,20 @@ export class ERC1155ProxyWrapper {
valueMultiplier: BigNumber,
receiverCallbackData: string,
authorizedSender: string,
extraData?: string,
): Promise<string> {
assetData_?: string,
): Promise<TransactionReceiptWithDecodedLogs> {
this._validateProxyContractExistsOrThrow();
let encodedAssetData = assetDataUtils.encodeERC1155AssetData(
contractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
if (!_.isUndefined(extraData)) {
encodedAssetData = `${encodedAssetData}${extraData}`;
}
const assetData =
assetData_ === undefined
? assetDataUtils.encodeERC1155AssetData(
contractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
)
: assetData_;
const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData(
encodedAssetData,
assetData,
from,
to,
valueMultiplier,
@@ -128,46 +184,9 @@ export class ERC1155ProxyWrapper {
to: (this._proxyContract as ERC1155ProxyContract).address,
data,
from: authorizedSender,
gas: 300000,
});
return txHash;
}
/**
* @dev transfers erc1155 fungible/non-fungible tokens.
* @param from source address
* @param to destination address
* @param contractAddress address of erc155 contract
* @param tokensToTransfer array of erc1155 tokens to transfer
* @param valuesToTransfer array of corresponding values for each erc1155 token to transfer
* @param valueMultiplier each value in `valuesToTransfer` is multiplied by this
* @param receiverCallbackData callback data if `to` is a contract
* @param authorizedSender sender of `transferFrom` transaction
* @param extraData extra data to append to `transferFrom` transaction. Optional.
* @return tranasction receipt with decoded logs.
*/
public async transferFromWithLogsAsync(
from: string,
to: string,
contractAddress: string,
tokensToTransfer: BigNumber[],
valuesToTransfer: BigNumber[],
valueMultiplier: BigNumber,
receiverCallbackData: string,
authorizedSender: string,
extraData?: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(
await this.transferFromAsync(
from,
to,
contractAddress,
tokensToTransfer,
valuesToTransfer,
valueMultiplier,
receiverCallbackData,
authorizedSender,
extraData,
),
);
const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
return txReceipt;
}
/**
@@ -199,10 +218,10 @@ export class ERC1155ProxyWrapper {
// Mint tokens for each owner for this token
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
// tslint:disable-next-line:no-unused-variable
if (_.isUndefined(fungibleHoldingsByOwner[tokenOwnerAddress])) {
if (fungibleHoldingsByOwner[tokenOwnerAddress] === undefined) {
fungibleHoldingsByOwner[tokenOwnerAddress] = {};
}
if (_.isUndefined(fungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress])) {
if (fungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress] === undefined) {
fungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress] = {};
}
fungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress][tokenIdAsString] =
@@ -221,13 +240,13 @@ export class ERC1155ProxyWrapper {
const tokenIdAsString = tokenId.toString();
this._nonFungibleTokenIds.push(tokenIdAsString);
_.each(this._tokenOwnerAddresses, async (tokenOwnerAddress: string, i: number) => {
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress])) {
if (nonFungibleHoldingsByOwner[tokenOwnerAddress] === undefined) {
nonFungibleHoldingsByOwner[tokenOwnerAddress] = {};
}
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress])) {
if (nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress] === undefined) {
nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress] = {};
}
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress][tokenIdAsString])) {
if (nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress][tokenIdAsString] === undefined) {
nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress][tokenIdAsString] = [];
}
this._nfts.push({ id: nftIds[i], tokenId });
@@ -278,26 +297,25 @@ export class ERC1155ProxyWrapper {
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
// Fungible tokens
for (const tokenId of this._fungibleTokenIds) {
if (_.isUndefined(tokenHoldingsByOwner[tokenOwnerAddress])) {
if (tokenHoldingsByOwner[tokenOwnerAddress] === undefined) {
tokenHoldingsByOwner[tokenOwnerAddress] = {};
}
if (_.isUndefined(tokenHoldingsByOwner[tokenOwnerAddress][tokenAddress])) {
if (tokenHoldingsByOwner[tokenOwnerAddress][tokenAddress] === undefined) {
tokenHoldingsByOwner[tokenOwnerAddress][tokenAddress] = {};
}
tokenHoldingsByOwner[tokenOwnerAddress][tokenAddress][tokenId] = balances[i++];
}
// Non-fungible tokens
for (const nft of this._nfts) {
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress])) {
if (nonFungibleHoldingsByOwner[tokenOwnerAddress] === undefined) {
nonFungibleHoldingsByOwner[tokenOwnerAddress] = {};
}
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress])) {
if (nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress] === undefined) {
nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress] = {};
}
if (
_.isUndefined(
nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress][nft.tokenId.toString()],
)
nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress][nft.tokenId.toString()] ===
undefined
) {
nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress][nft.tokenId.toString()] = [];
}
@@ -348,25 +366,25 @@ export class ERC1155ProxyWrapper {
const tokenWrapper = _.find(this._dummyTokenWrappers, (wrapper: Erc1155Wrapper) => {
return wrapper.getContract().address === contractAddress;
});
if (_.isUndefined(tokenWrapper)) {
if (tokenWrapper === undefined) {
throw new Error(`Contract: ${contractAddress} was not deployed through ERC1155ProxyWrapper`);
}
return tokenWrapper;
}
private _getContractFromAddress(tokenAddress: string): ERC1155MintableContract {
const tokenContractIfExists = _.find(this._dummyTokenWrappers, c => c.getContract().address === tokenAddress);
if (_.isUndefined(tokenContractIfExists)) {
if (tokenContractIfExists === undefined) {
throw new Error(`Token: ${tokenAddress} was not deployed through ERC1155ProxyWrapper`);
}
return tokenContractIfExists.getContract();
}
private _validateDummyTokenContractsExistOrThrow(): void {
if (_.isUndefined(this._dummyTokenWrappers)) {
if (this._dummyTokenWrappers === undefined) {
throw new Error('Dummy ERC1155 tokens not yet deployed, please call "deployDummyTokensAsync"');
}
}
private _validateProxyContractExistsOrThrow(): void {
if (_.isUndefined(this._proxyContract)) {
if (this._proxyContract === undefined) {
throw new Error('ERC1155 proxy contract not yet deployed, please call "deployProxyAsync"');
}
}

View File

@@ -2,7 +2,6 @@ import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contra
import { constants, ERC20BalancesByOwner, txDefaults } from '@0x/contracts-test-utils';
import { assetDataUtils } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import { ZeroExProvider } from 'ethereum-types';
import * as _ from 'lodash';
@@ -11,7 +10,6 @@ import { artifacts, ERC20ProxyContract } from '../../src';
export class ERC20Wrapper {
private readonly _tokenOwnerAddresses: string[];
private readonly _contractOwnerAddress: string;
private readonly _web3Wrapper: Web3Wrapper;
private readonly _provider: ZeroExProvider;
private readonly _dummyTokenContracts: DummyERC20TokenContract[];
private _proxyContract?: ERC20ProxyContract;
@@ -25,7 +23,6 @@ export class ERC20Wrapper {
*/
constructor(provider: ZeroExProvider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
this._dummyTokenContracts = [];
this._web3Wrapper = new Web3Wrapper(provider);
this._provider = provider;
this._tokenOwnerAddresses = tokenOwnerAddresses;
this._contractOwnerAddress = contractOwnerAddress;
@@ -67,20 +64,16 @@ export class ERC20Wrapper {
this._validateProxyContractExistsOrThrow();
for (const dummyTokenContract of this._dummyTokenContracts) {
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
await this._web3Wrapper.awaitTransactionSuccessAsync(
await dummyTokenContract.setBalance.sendTransactionAsync(
tokenOwnerAddress,
constants.INITIAL_ERC20_BALANCE,
{ from: this._contractOwnerAddress },
),
await dummyTokenContract.setBalance.awaitTransactionSuccessAsync(
tokenOwnerAddress,
constants.INITIAL_ERC20_BALANCE,
{ from: this._contractOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await this._web3Wrapper.awaitTransactionSuccessAsync(
await dummyTokenContract.approve.sendTransactionAsync(
(this._proxyContract as ERC20ProxyContract).address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: tokenOwnerAddress },
),
await dummyTokenContract.approve.awaitTransactionSuccessAsync(
(this._proxyContract as ERC20ProxyContract).address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: tokenOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
@@ -93,10 +86,10 @@ export class ERC20Wrapper {
}
public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(assetData);
await this._web3Wrapper.awaitTransactionSuccessAsync(
await tokenContract.setBalance.sendTransactionAsync(userAddress, amount, {
from: this._contractOwnerAddress,
}),
await tokenContract.setBalance.awaitTransactionSuccessAsync(
userAddress,
amount,
{ from: this._contractOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
@@ -109,10 +102,10 @@ export class ERC20Wrapper {
public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(assetData);
const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
await this._web3Wrapper.awaitTransactionSuccessAsync(
await tokenContract.approve.sendTransactionAsync(proxyAddress, amount, {
from: userAddress,
}),
await tokenContract.approve.awaitTransactionSuccessAsync(
proxyAddress,
amount,
{ from: userAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
@@ -133,7 +126,7 @@ export class ERC20Wrapper {
_.forEach(balances, (balance, balanceIndex) => {
const tokenAddress = balanceInfo[balanceIndex].tokenAddress;
const tokenOwnerAddress = balanceInfo[balanceIndex].tokenOwnerAddress;
if (_.isUndefined(balancesByOwner[tokenOwnerAddress])) {
if (balancesByOwner[tokenOwnerAddress] === undefined) {
balancesByOwner[tokenOwnerAddress] = {};
}
const wrappedBalance = new BigNumber(balance);
@@ -142,7 +135,7 @@ export class ERC20Wrapper {
return balancesByOwner;
}
public addDummyTokenContract(dummy: DummyERC20TokenContract): void {
if (!_.isUndefined(this._dummyTokenContracts)) {
if (this._dummyTokenContracts !== undefined) {
this._dummyTokenContracts.push(dummy);
}
}
@@ -160,18 +153,18 @@ export class ERC20Wrapper {
const erc20ProxyData = assetDataUtils.decodeERC20AssetData(assetData);
const tokenAddress = erc20ProxyData.tokenAddress;
const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
if (_.isUndefined(tokenContractIfExists)) {
if (tokenContractIfExists === undefined) {
throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);
}
return tokenContractIfExists;
}
private _validateDummyTokenContractsExistOrThrow(): void {
if (_.isUndefined(this._dummyTokenContracts)) {
if (this._dummyTokenContracts === undefined) {
throw new Error('Dummy ERC20 tokens not yet deployed, please call "deployDummyTokensAsync"');
}
}
private _validateProxyContractExistsOrThrow(): void {
if (_.isUndefined(this._proxyContract)) {
if (this._proxyContract === undefined) {
throw new Error('ERC20 proxy contract not yet deployed, please call "deployProxyAsync"');
}
}

View File

@@ -2,7 +2,6 @@ import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/cont
import { constants, ERC721TokenIdsByOwner, txDefaults } from '@0x/contracts-test-utils';
import { generatePseudoRandomSalt } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import { ZeroExProvider } from 'ethereum-types';
import * as _ from 'lodash';
@@ -11,14 +10,12 @@ import { artifacts, ERC721ProxyContract } from '../../src';
export class ERC721Wrapper {
private readonly _tokenOwnerAddresses: string[];
private readonly _contractOwnerAddress: string;
private readonly _web3Wrapper: Web3Wrapper;
private readonly _provider: ZeroExProvider;
private readonly _dummyTokenContracts: DummyERC721TokenContract[];
private _proxyContract?: ERC721ProxyContract;
private _proxyIdIfExists?: string;
private _initialTokenIdsByOwner: ERC721TokenIdsByOwner = {};
constructor(provider: ZeroExProvider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
this._web3Wrapper = new Web3Wrapper(provider);
this._provider = provider;
this._dummyTokenContracts = [];
this._tokenOwnerAddresses = tokenOwnerAddresses;
@@ -62,12 +59,12 @@ export class ERC721Wrapper {
for (const i of _.times(constants.NUM_ERC721_TOKENS_TO_MINT)) {
const tokenId = generatePseudoRandomSalt();
await this.mintAsync(dummyTokenContract.address, tokenId, tokenOwnerAddress);
if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress])) {
if (this._initialTokenIdsByOwner[tokenOwnerAddress] === undefined) {
this._initialTokenIdsByOwner[tokenOwnerAddress] = {
[dummyTokenContract.address]: [],
};
}
if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address])) {
if (this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address] === undefined) {
this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address] = [];
}
this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address].push(tokenId);
@@ -91,20 +88,20 @@ export class ERC721Wrapper {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
await this._web3Wrapper.awaitTransactionSuccessAsync(
await tokenContract.setApprovalForAll.sendTransactionAsync(proxyAddress, isApproved, {
from: tokenOwner,
}),
await tokenContract.setApprovalForAll.awaitTransactionSuccessAsync(
proxyAddress,
isApproved,
{ from: tokenOwner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
public async approveAsync(to: string, tokenAddress: string, tokenId: BigNumber): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
await this._web3Wrapper.awaitTransactionSuccessAsync(
await tokenContract.approve.sendTransactionAsync(to, tokenId, {
from: tokenOwner,
}),
await tokenContract.approve.awaitTransactionSuccessAsync(
to,
tokenId,
{ from: tokenOwner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
@@ -115,28 +112,29 @@ export class ERC721Wrapper {
userAddress: string,
): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
await this._web3Wrapper.awaitTransactionSuccessAsync(
await tokenContract.transferFrom.sendTransactionAsync(currentOwner, userAddress, tokenId, {
from: currentOwner,
}),
await tokenContract.transferFrom.awaitTransactionSuccessAsync(
currentOwner,
userAddress,
tokenId,
{ from: currentOwner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
public async mintAsync(tokenAddress: string, tokenId: BigNumber, userAddress: string): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
await this._web3Wrapper.awaitTransactionSuccessAsync(
await tokenContract.mint.sendTransactionAsync(userAddress, tokenId, {
from: this._contractOwnerAddress,
}),
await tokenContract.mint.awaitTransactionSuccessAsync(
userAddress,
tokenId,
{ from: this._contractOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
public async burnAsync(tokenAddress: string, tokenId: BigNumber, owner: string): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
await this._web3Wrapper.awaitTransactionSuccessAsync(
await tokenContract.burn.sendTransactionAsync(owner, tokenId, {
from: this._contractOwnerAddress,
}),
await tokenContract.burn.awaitTransactionSuccessAsync(
owner,
tokenId,
{ from: this._contractOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
@@ -189,12 +187,12 @@ export class ERC721Wrapper {
_.forEach(tokenOwnerAddresses, (tokenOwnerAddress, ownerIndex) => {
const tokenAddress = tokenInfo[ownerIndex].tokenAddress;
const tokenId = tokenInfo[ownerIndex].tokenId;
if (_.isUndefined(tokenIdsByOwner[tokenOwnerAddress])) {
if (tokenIdsByOwner[tokenOwnerAddress] === undefined) {
tokenIdsByOwner[tokenOwnerAddress] = {
[tokenAddress]: [],
};
}
if (_.isUndefined(tokenIdsByOwner[tokenOwnerAddress][tokenAddress])) {
if (tokenIdsByOwner[tokenOwnerAddress][tokenAddress] === undefined) {
tokenIdsByOwner[tokenOwnerAddress][tokenAddress] = [];
}
tokenIdsByOwner[tokenOwnerAddress][tokenAddress].push(tokenId);
@@ -210,18 +208,18 @@ export class ERC721Wrapper {
}
private _getTokenContractFromAssetData(tokenAddress: string): DummyERC721TokenContract {
const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
if (_.isUndefined(tokenContractIfExists)) {
if (tokenContractIfExists === undefined) {
throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);
}
return tokenContractIfExists;
}
private _validateDummyTokenContractsExistOrThrow(): void {
if (_.isUndefined(this._dummyTokenContracts)) {
if (this._dummyTokenContracts === undefined) {
throw new Error('Dummy ERC721 tokens not yet deployed, please call "deployDummyTokensAsync"');
}
}
private _validateProxyContractExistsOrThrow(): void {
if (_.isUndefined(this._proxyContract)) {
if (this._proxyContract === undefined) {
throw new Error('ERC721 proxy contract not yet deployed, please call "deployProxyAsync"');
}
}

View File

@@ -10,7 +10,9 @@
"generated-artifacts/IAssetProxy.json",
"generated-artifacts/IAuthorizable.json",
"generated-artifacts/MixinAuthorizable.json",
"generated-artifacts/MultiAssetProxy.json"
"generated-artifacts/MultiAssetProxy.json",
"generated-artifacts/StaticCallProxy.json",
"generated-artifacts/TestStaticCallTarget.json"
],
"exclude": ["./deploy/solc/solc_bin"]
}

View File

@@ -1,4 +1,73 @@
[
{
"timestamp": 1563006338,
"version": "2.0.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1558712885,
"version": "2.0.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557961111,
"version": "2.0.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557799313,
"version": "2.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557507213,
"version": "2.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.0.0",
"changes": [
{
"note": "Make `decodeOrdersFromFillData`, `getCoordinatorApprovalHash`, and `getTransactionHash` public",
"pr": 1729
},
{
"note": "Make `assertValidTransactionOrdersApproval` internal",
"pr": 1729
}
],
"timestamp": 1554997931
},
{
"version": "1.1.0",
"changes": [
{
"note": "Run Web3ProviderEngine without excess block polling",
"pr": 1695
}
],
"timestamp": 1553183790
},
{
"version": "1.0.0",
"changes": [

View File

@@ -5,6 +5,35 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.0.5 - _July 13, 2019_
* Dependencies updated
## v2.0.4 - _May 24, 2019_
* Dependencies updated
## v2.0.3 - _May 15, 2019_
* Dependencies updated
## v2.0.2 - _May 14, 2019_
* Dependencies updated
## v2.0.1 - _May 10, 2019_
* Dependencies updated
## v2.0.0 - _April 11, 2019_
* Make `decodeOrdersFromFillData`, `getCoordinatorApprovalHash`, and `getTransactionHash` public (#1729)
* Make `assertValidTransactionOrdersApproval` internal (#1729)
## v1.1.0 - _March 21, 2019_
* Run Web3ProviderEngine without excess block polling (#1695)
## v1.0.0 - _March 20, 2019_
* Created Coordinator package

View File

@@ -1,7 +1,7 @@
{
"artifactsDir": "./generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": true,
"useDockerisedSolc": false,
"compilerSettings": {
"evmVersion": "constantinople",
"optimizer": {
@@ -13,6 +13,7 @@
"*": {
"*": [
"abi",
"devdoc",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
@@ -21,10 +22,5 @@
}
}
},
"contracts": [
"src/Coordinator.sol",
"src/registry/CoordinatorRegistry.sol",
"test/TestLibs.sol",
"test/TestMixins.sol"
]
"contracts": ["src/Coordinator.sol", "src/registry/CoordinatorRegistry.sol"]
}

View File

@@ -58,7 +58,7 @@ contract MixinCoordinatorApprovalVerifier is
view
{
// Get the orders from the the Exchange calldata in the 0x transaction
LibOrder.Order[] memory orders = decodeFillDataOrders(transaction.data);
LibOrder.Order[] memory orders = decodeOrdersFromFillData(transaction.data);
// No approval is required for non-fill methods
if (orders.length > 0) {
@@ -74,6 +74,57 @@ contract MixinCoordinatorApprovalVerifier is
}
}
/// @dev Decodes the orders from Exchange calldata representing any fill method.
/// @param data Exchange calldata representing a fill method.
/// @return The orders from the Exchange calldata.
function decodeOrdersFromFillData(bytes memory data)
public
pure
returns (LibOrder.Order[] memory orders)
{
bytes4 selector = data.readBytes4(0);
if (
selector == FILL_ORDER_SELECTOR ||
selector == FILL_ORDER_NO_THROW_SELECTOR ||
selector == FILL_OR_KILL_ORDER_SELECTOR
) {
// Decode single order
(LibOrder.Order memory order) = abi.decode(
data.slice(4, data.length),
(LibOrder.Order)
);
orders = new LibOrder.Order[](1);
orders[0] = order;
} else if (
selector == BATCH_FILL_ORDERS_SELECTOR ||
selector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR ||
selector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR ||
selector == MARKET_BUY_ORDERS_SELECTOR ||
selector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR ||
selector == MARKET_SELL_ORDERS_SELECTOR ||
selector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR
) {
// Decode all orders
// solhint-disable indent
(orders) = abi.decode(
data.slice(4, data.length),
(LibOrder.Order[])
);
} else if (selector == MATCH_ORDERS_SELECTOR) {
// Decode left and right orders
(LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder) = abi.decode(
data.slice(4, data.length),
(LibOrder.Order, LibOrder.Order)
);
// Create array of orders
orders = new LibOrder.Order[](2);
orders[0] = leftOrder;
orders[1] = rightOrder;
}
return orders;
}
/// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param orders Array of order structs containing order specifications.
@@ -89,7 +140,7 @@ contract MixinCoordinatorApprovalVerifier is
uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures
)
public
internal
view
{
// Verify that Ethereum tx signer is the same as the approved txOrigin
@@ -149,55 +200,4 @@ contract MixinCoordinatorApprovalVerifier is
);
}
}
/// @dev Decodes the orders from Exchange calldata representing any fill method.
/// @param data Exchange calldata representing a fill method.
/// @return The orders from the Exchange calldata.
function decodeFillDataOrders(bytes memory data)
internal
pure
returns (LibOrder.Order[] memory orders)
{
bytes4 selector = data.readBytes4(0);
if (
selector == FILL_ORDER_SELECTOR ||
selector == FILL_ORDER_NO_THROW_SELECTOR ||
selector == FILL_OR_KILL_ORDER_SELECTOR
) {
// Decode single order
(LibOrder.Order memory order) = abi.decode(
data.slice(4, data.length),
(LibOrder.Order)
);
orders = new LibOrder.Order[](1);
orders[0] = order;
} else if (
selector == BATCH_FILL_ORDERS_SELECTOR ||
selector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR ||
selector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR ||
selector == MARKET_BUY_ORDERS_SELECTOR ||
selector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR ||
selector == MARKET_SELL_ORDERS_SELECTOR ||
selector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR
) {
// Decode all orders
// solhint-disable indent
(orders) = abi.decode(
data.slice(4, data.length),
(LibOrder.Order[])
);
} else if (selector == MATCH_ORDERS_SELECTOR) {
// Decode left and right orders
(LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder) = abi.decode(
data.slice(4, data.length),
(LibOrder.Order, LibOrder.Order)
);
// Create array of orders
orders = new LibOrder.Order[](2);
orders[0] = leftOrder;
orders[1] = rightOrder;
}
return orders;
}
}

View File

@@ -42,21 +42,11 @@ contract ICoordinatorApprovalVerifier {
public
view;
/// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param orders Array of order structs containing order specifications.
/// @param txOrigin Required signer of Ethereum transaction calling this function.
/// @param transactionSignature Proof that the transaction has been signed by the signer.
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each corresponding approval signature expires.
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.
function assertValidTransactionOrdersApproval(
LibZeroExTransaction.ZeroExTransaction memory transaction,
LibOrder.Order[] memory orders,
address txOrigin,
bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures
)
/// @dev Decodes the orders from Exchange calldata representing any fill method.
/// @param data Exchange calldata representing a fill method.
/// @return The orders from the Exchange calldata.
function decodeOrdersFromFillData(bytes memory data)
public
view;
pure
returns (LibOrder.Order[] memory orders);
}

View File

@@ -17,6 +17,7 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
import "./LibEIP712Domain.sol";
@@ -37,16 +38,16 @@ contract LibCoordinatorApproval is
struct CoordinatorApproval {
address txOrigin; // Required signer of Ethereum transaction that is submitting approval.
bytes32 transactionHash; // EIP712 hash of the transaction, using the domain separator of this contract.
bytes32 transactionHash; // EIP712 hash of the transaction.
bytes transactionSignature; // Signature of the 0x transaction.
uint256 approvalExpirationTimeSeconds; // Timestamp in seconds for which the signature expires.
uint256 approvalExpirationTimeSeconds; // Timestamp in seconds for which the approval expires.
}
/// @dev Calculated the EIP712 hash of the Coordinator approval mesasage using the domain separator of this contract.
/// @param approval Coordinator approval message containing the transaction hash, transaction signature, and expiration of the approval.
/// @return EIP712 hash of the Coordinator approval message with the domain separator of this contract.
function getCoordinatorApprovalHash(CoordinatorApproval memory approval)
internal
public
view
returns (bytes32 approvalHash)
{
@@ -71,9 +72,10 @@ contract LibCoordinatorApproval is
// Assembly for more efficiently computing:
// keccak256(abi.encodePacked(
// EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH,
// approval.txOrigin,
// approval.transactionHash,
// keccak256(approval.transactionSignature)
// approval.expiration,
// approval.approvalExpirationTimeSeconds,
// ));
assembly {

View File

@@ -17,6 +17,7 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
import "./LibEIP712Domain.sol";
@@ -40,11 +41,11 @@ contract LibZeroExTransaction is
bytes data; // AbiV2 encoded calldata.
}
/// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of this contract.
/// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @return EIP712 hash of the transaction with the domain separator of this contract.
function getTransactionHash(ZeroExTransaction memory transaction)
internal
public
view
returns (bytes32 transactionHash)
{

View File

@@ -26,11 +26,21 @@ import "../interfaces/ICoordinatorApprovalVerifier.sol";
contract MCoordinatorApprovalVerifier is
ICoordinatorApprovalVerifier
{
/// @dev Decodes the orders from Exchange calldata representing any fill method.
/// @param data Exchange calldata representing a fill method.
/// @return The orders from the Exchange calldata.
function decodeFillDataOrders(bytes memory data)
/// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param orders Array of order structs containing order specifications.
/// @param txOrigin Required signer of Ethereum transaction calling this function.
/// @param transactionSignature Proof that the transaction has been signed by the signer.
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each corresponding approval signature expires.
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.
function assertValidTransactionOrdersApproval(
LibZeroExTransaction.ZeroExTransaction memory transaction,
LibOrder.Order[] memory orders,
address txOrigin,
bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures
)
internal
pure
returns (LibOrder.Order[] memory orders);
view;
}

View File

@@ -1,61 +0,0 @@
/*
Copyright 2018 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.5;
pragma experimental "ABIEncoderV2";
import "../src/libs/LibConstants.sol";
import "../src/libs/LibCoordinatorApproval.sol";
import "../src/libs/LibZeroExTransaction.sol";
// solhint-disable no-empty-blocks
contract TestLibs is
LibConstants,
LibCoordinatorApproval,
LibZeroExTransaction
{
constructor (address _exchange)
public
LibConstants(_exchange)
{}
/// @dev Calculated the EIP712 hash of the Coordinator approval mesasage using the domain separator of this contract.
/// @param approval Coordinator approval message containing the transaction hash, transaction signature, and expiration of the approval.
/// @return EIP712 hash of the Coordinator approval message with the domain separator of this contract.
function publicGetCoordinatorApprovalHash(CoordinatorApproval memory approval)
public
view
returns (bytes32 approvalHash)
{
approvalHash = getCoordinatorApprovalHash(approval);
return approvalHash;
}
/// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @return EIP712 hash of the transaction with the domain separator of the Exchange contract.
function publicGetTransactionHash(ZeroExTransaction memory transaction)
public
view
returns (bytes32 transactionHash)
{
transactionHash = getTransactionHash(transaction);
return transactionHash;
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-coordinator",
"version": "1.0.0",
"version": "2.0.5",
"engines": {
"node": ">=6.12"
},
@@ -24,6 +24,7 @@
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html",
@@ -33,7 +34,7 @@
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
},
"config": {
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry|TestLibs|TestMixins).json",
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
@@ -46,12 +47,12 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
"devDependencies": {
"@0x/abi-gen": "^2.0.7",
"@0x/contracts-gen": "^1.0.6",
"@0x/contracts-test-utils": "^3.1.0",
"@0x/dev-utils": "^2.1.4",
"@0x/sol-compiler": "^3.1.4",
"@0x/tslint-config": "^3.0.0",
"@0x/abi-gen": "^2.1.0",
"@0x/contracts-gen": "^1.0.10",
"@0x/contracts-test-utils": "^3.1.8",
"@0x/dev-utils": "^2.2.4",
"@0x/sol-compiler": "^3.1.9",
"@0x/tslint-config": "^3.0.1",
"@types/lodash": "4.14.104",
"@types/node": "*",
"chai": "^4.0.1",
@@ -67,18 +68,18 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.0.3",
"@0x/contracts-asset-proxy": "^2.0.0",
"@0x/contracts-erc20": "^2.0.0",
"@0x/contracts-exchange": "1.0.2",
"@0x/contracts-exchange-libs": "^2.0.0",
"@0x/contracts-utils": "^3.0.0",
"@0x/order-utils": "^7.1.0",
"@0x/types": "^2.2.0",
"@0x/typescript-typings": "^4.2.0",
"@0x/utils": "^4.2.3",
"@0x/web3-wrapper": "^6.0.3",
"ethereum-types": "^2.1.1",
"@0x/base-contract": "^5.1.1",
"@0x/contracts-asset-proxy": "^2.2.0",
"@0x/contracts-erc20": "^2.2.6",
"@0x/contracts-exchange": "^2.1.6",
"@0x/contracts-exchange-libs": "^3.0.0",
"@0x/contracts-utils": "^3.1.7",
"@0x/order-utils": "^8.2.0",
"@0x/types": "^2.4.0",
"@0x/typescript-typings": "^4.2.3",
"@0x/utils": "^4.4.0",
"@0x/web3-wrapper": "^6.0.7",
"ethereum-types": "^2.1.3",
"ethereumjs-util": "^5.1.1",
"lodash": "^4.17.11"
},

View File

@@ -7,11 +7,7 @@ import { ContractArtifact } from 'ethereum-types';
import * as Coordinator from '../generated-artifacts/Coordinator.json';
import * as CoordinatorRegistry from '../generated-artifacts/CoordinatorRegistry.json';
import * as TestLibs from '../generated-artifacts/TestLibs.json';
import * as TestMixins from '../generated-artifacts/TestMixins.json';
export const artifacts = {
Coordinator: Coordinator as ContractArtifact,
CoordinatorRegistry: CoordinatorRegistry as ContractArtifact,
TestLibs: TestLibs as ContractArtifact,
TestMixins: TestMixins as ContractArtifact,
};

View File

@@ -5,5 +5,3 @@
*/
export * from '../generated-wrappers/coordinator';
export * from '../generated-wrappers/coordinator_registry';
export * from '../generated-wrappers/test_libs';
export * from '../generated-wrappers/test_mixins';

View File

@@ -435,7 +435,7 @@ describe('Coordinator tests', () => {
describe('cancels', () => {
it('cancelOrder call should be successful without an approval', async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDER, orders);
const transaction = makerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync(

View File

@@ -1,8 +1,10 @@
import { env, EnvVars } from '@0x/dev-utils';
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
import { providerUtils } from '@0x/utils';
before('start web3 provider', () => {
provider.start();
providerUtils.startProviderEngine(provider);
});
after('generate coverage report', async () => {
if (env.parseBoolean(EnvVars.SolidityCoverage)) {

View File

@@ -4,14 +4,14 @@ import { transactionHashUtils } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import { artifacts, hashUtils, TestLibsContract } from '../src';
import { artifacts, CoordinatorContract, hashUtils } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('Libs tests', () => {
let testLibs: TestLibsContract;
let coordinatorContract: CoordinatorContract;
const exchangeAddress = addressUtils.generatePseudoRandomAddress();
before(async () => {
@@ -21,8 +21,8 @@ describe('Libs tests', () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
testLibs = await TestLibsContract.deployFrom0xArtifactAsync(
artifacts.TestLibs,
coordinatorContract = await CoordinatorContract.deployFrom0xArtifactAsync(
artifacts.Coordinator,
provider,
txDefaults,
exchangeAddress,
@@ -44,7 +44,7 @@ describe('Libs tests', () => {
data: '0x1234',
};
const expectedTxHash = transactionHashUtils.getTransactionHashHex(tx);
const txHash = await testLibs.publicGetTransactionHash.callAsync(tx);
const txHash = await coordinatorContract.getTransactionHash.callAsync(tx);
expect(expectedTxHash).to.eq(txHash);
});
});
@@ -68,11 +68,11 @@ describe('Libs tests', () => {
};
const expectedApprovalHash = hashUtils.getApprovalHashHex(
signedTx,
testLibs.address,
coordinatorContract.address,
txOrigin,
approvalExpirationTimeSeconds,
);
const approvalHash = await testLibs.publicGetCoordinatorApprovalHash.callAsync(approval);
const approvalHash = await coordinatorContract.getCoordinatorApprovalHash.callAsync(approval);
expect(expectedApprovalHash).to.eq(approvalHash);
});
});

View File

@@ -16,7 +16,7 @@ import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as ethUtil from 'ethereumjs-util';
import { ApprovalFactory, artifacts, constants, exchangeDataEncoder, TestMixinsContract } from '../src';
import { ApprovalFactory, artifacts, constants, CoordinatorContract, exchangeDataEncoder } from '../src';
chaiSetup.configure();
const expect = chai.expect;
@@ -26,7 +26,7 @@ describe('Mixins tests', () => {
let transactionSignerAddress: string;
let approvalSignerAddress1: string;
let approvalSignerAddress2: string;
let mixins: TestMixinsContract;
let mixins: CoordinatorContract;
let transactionFactory: TransactionFactory;
let approvalFactory1: ApprovalFactory;
let approvalFactory2: ApprovalFactory;
@@ -40,8 +40,8 @@ describe('Mixins tests', () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
mixins = await TestMixinsContract.deployFrom0xArtifactAsync(
artifacts.TestMixins,
mixins = await CoordinatorContract.deployFrom0xArtifactAsync(
artifacts.Coordinator,
provider,
txDefaults,
exchangeAddress,
@@ -135,6 +135,70 @@ describe('Mixins tests', () => {
});
});
describe('decodeOrdersFromFillData', () => {
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
const decodedSignedOrders = decodedOrders.map(order => ({
...order,
exchangeAddress: devConstants.NULL_ADDRESS,
signature: devConstants.NULL_BYTES,
}));
expect(orders).to.deep.eq(decodedSignedOrders);
});
}
for (const fnName of constants.BATCH_FILL_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
const decodedSignedOrders = decodedOrders.map(order => ({
...order,
exchangeAddress: devConstants.NULL_ADDRESS,
signature: devConstants.NULL_BYTES,
}));
expect(orders).to.deep.eq(decodedSignedOrders);
});
}
for (const fnName of constants.MARKET_FILL_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
const decodedSignedOrders = decodedOrders.map(order => ({
...order,
exchangeAddress: devConstants.NULL_ADDRESS,
signature: devConstants.NULL_BYTES,
}));
expect(orders).to.deep.eq(decodedSignedOrders);
});
}
for (const fnName of [constants.CANCEL_ORDER, constants.BATCH_CANCEL_ORDERS, constants.CANCEL_ORDERS_UP_TO]) {
it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
const emptyArray: any[] = [];
expect(emptyArray).to.deep.eq(decodedOrders);
});
}
it('should decode an empty array for invalid data', async () => {
const data = '0x0123456789';
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
const emptyArray: any[] = [];
expect(emptyArray).to.deep.eq(decodedOrders);
});
it('should revert if data is less than 4 bytes long', async () => {
const data = '0x010203';
await expectContractCallFailedAsync(
mixins.decodeOrdersFromFillData.callAsync(data),
RevertReason.LibBytesGreaterOrEqualTo4LengthRequired,
);
});
});
describe('Single order approvals', () => {
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
@@ -148,15 +212,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -181,15 +236,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -203,15 +249,6 @@ describe('Mixins tests', () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
approvalSignerAddress1,
transaction.signature,
[],
[],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
@@ -234,15 +271,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
approvalSignerAddress1,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
@@ -256,15 +284,6 @@ describe('Mixins tests', () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
approvalSignerAddress1,
transaction.signature,
[],
[],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
@@ -288,18 +307,6 @@ describe('Mixins tests', () => {
approvalExpirationTimeSeconds,
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[signature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -323,18 +330,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -358,18 +353,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidOrigin,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -401,15 +384,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -433,15 +407,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -458,15 +423,6 @@ describe('Mixins tests', () => {
}));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -487,15 +443,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -521,15 +468,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -543,15 +481,6 @@ describe('Mixins tests', () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
approvalSignerAddress1,
transaction.signature,
[],
[],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
@@ -572,18 +501,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.signature],
{ from: approvalSignerAddress1 },
),
RevertReason.InvalidOrigin,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -600,18 +517,6 @@ describe('Mixins tests', () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -636,18 +541,6 @@ describe('Mixins tests', () => {
approvalExpirationTimeSeconds,
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[signature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -677,18 +570,6 @@ describe('Mixins tests', () => {
approvalExpirationTimeSeconds,
);
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.signature, approvalSignature2],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -713,18 +594,6 @@ describe('Mixins tests', () => {
approvalExpirationTimeSeconds,
);
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
approvalSignerAddress1,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature2],
{ from: approvalSignerAddress1 },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -754,18 +623,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds2,
);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -789,18 +646,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
approvalSignerAddress1,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.signature],
{ from: approvalSignerAddress1 },
),
RevertReason.ApprovalExpired,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -824,18 +669,6 @@ describe('Mixins tests', () => {
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval1.signature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidOrigin,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
@@ -851,9 +684,9 @@ describe('Mixins tests', () => {
}
});
describe('cancels', () => {
it('should allow the tx signer to call `cancelOrders` without approval', async () => {
it('should allow the tx signer to call `cancelOrder` without approval', async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDER, orders);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,

View File

@@ -5,7 +5,7 @@ export const constants = {
BATCH_FILL_FN_NAMES: ['batchFillOrders', 'batchFillOrKillOrders', 'batchFillOrdersNoThrow'],
MARKET_FILL_FN_NAMES: ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow'],
MATCH_ORDERS: 'matchOrders',
CANCEL_ORDERS: 'cancelOrders',
CANCEL_ORDER: 'cancelOrder',
BATCH_CANCEL_ORDERS: 'batchCancelOrders',
CANCEL_ORDERS_UP_TO: 'cancelOrdersUpTo',
TIME_BUFFER: new BigNumber(1000),

View File

@@ -1,7 +1,6 @@
import { LogDecoder, txDefaults } from '@0x/contracts-test-utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import { TransactionReceiptWithDecodedLogs, ZeroExProvider } from 'ethereum-types';
import * as _ from 'lodash';
import { artifacts, CoordinatorRegistryContract } from '../../src';
@@ -26,7 +25,7 @@ export class CoordinatorRegistryWrapper {
this._provider,
txDefaults,
);
if (_.isUndefined(this._coordinatorRegistryContract)) {
if (this._coordinatorRegistryContract === undefined) {
throw new Error(`Failed to deploy Coordinator Registry contract.`);
}
return this._coordinatorRegistryContract;
@@ -56,7 +55,7 @@ export class CoordinatorRegistryWrapper {
return coordinatorEndpoint;
}
private _assertCoordinatorRegistryDeployed(): void {
if (_.isUndefined(this._coordinatorRegistryContract)) {
if (this._coordinatorRegistryContract === undefined) {
throw new Error(
'The Coordinator Registry contract was not deployed through the CoordinatorRegistryWrapper. Call `deployCoordinatorRegistryAsync` to deploy.',
);

View File

@@ -1,4 +1,4 @@
import { artifacts, IExchangeContract } from '@0x/contracts-exchange';
import { IExchangeContract } from '@0x/contracts-exchange';
import { constants as devConstants, provider } from '@0x/contracts-test-utils';
import { SignedOrder } from '@0x/types';
@@ -6,11 +6,7 @@ import { constants } from './index';
export const exchangeDataEncoder = {
encodeOrdersToExchangeData(fnName: string, orders: SignedOrder[]): string {
const exchangeInstance = new IExchangeContract(
artifacts.IExchange.compilerOutput.abi,
devConstants.NULL_ADDRESS,
provider,
);
const exchangeInstance = new IExchangeContract(devConstants.NULL_ADDRESS, provider);
let data;
if (constants.SINGLE_FILL_FN_NAMES.indexOf(fnName) !== -1) {
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
@@ -37,7 +33,7 @@ export const exchangeDataEncoder = {
orders[0].signature,
orders[1].signature,
);
} else if (fnName === constants.CANCEL_ORDERS) {
} else if (fnName === constants.CANCEL_ORDER) {
data = exchangeInstance.cancelOrder.getABIEncodedTransactionData(orders[0]);
} else if (fnName === constants.BATCH_CANCEL_ORDERS) {
data = exchangeInstance.batchCancelOrders.getABIEncodedTransactionData(orders);

View File

@@ -1,5 +1,4 @@
import { eip712Utils, transactionHashUtils } from '@0x/order-utils';
import { constants } from '@0x/order-utils/lib/src/constants';
import { eip712Utils } from '@0x/order-utils';
import { SignedZeroExTransaction } from '@0x/types';
import { BigNumber, signTypedDataUtils } from '@0x/utils';
import * as _ from 'lodash';
@@ -11,25 +10,11 @@ export const hashUtils = {
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
): Buffer {
const domain = {
name: constants.COORDINATOR_DOMAIN_NAME,
version: constants.COORDINATOR_DOMAIN_VERSION,
const typedData = eip712Utils.createCoordinatorApprovalTypedData(
transaction,
verifyingContractAddress,
};
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
const approval = {
txOrigin,
transactionHash,
transactionSignature: transaction.signature,
approvalExpirationTimeSeconds: approvalExpirationTimeSeconds.toString(),
};
const typedData = eip712Utils.createTypedData(
constants.COORDINATOR_APPROVAL_SCHEMA.name,
{
CoordinatorApproval: constants.COORDINATOR_APPROVAL_SCHEMA.parameters,
},
approval,
domain,
approvalExpirationTimeSeconds,
);
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
return hashBuffer;

View File

@@ -2,11 +2,6 @@
"extends": "../../tsconfig",
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": [
"generated-artifacts/Coordinator.json",
"generated-artifacts/CoordinatorRegistry.json",
"generated-artifacts/TestLibs.json",
"generated-artifacts/TestMixins.json"
],
"files": ["generated-artifacts/Coordinator.json", "generated-artifacts/CoordinatorRegistry.json"],
"exclude": ["./deploy/solc/solc_bin"]
}

View File

@@ -0,0 +1,40 @@
[
{
"timestamp": 1563006338,
"version": "0.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.0.1",
"changes": [
{
"note": "Create dev-utils package",
"pr": 1848
},
{
"note": "Add `LibAssetData` and `LibTransactionDecoder` contracts",
"pr": 1848
},
{
"note": "Refactor `LibAssetData` to only check 0x-specific allowances",
"pr": 1848
},
{
"note": "Refactor `LibAssetData` balance/allowance checks to never revert",
"pr": 1848
},
{
"note": "Refactor `OrderValidationUtils` to calculate `fillableTakerAssetAmount`",
"pr": 1848
},
{
"note": "Add support for StaticCallProxy",
"pr": 1863
}
]
}
]

View File

@@ -0,0 +1,19 @@
<!--
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
Edit the package's CHANGELOG.json file only.
-->
CHANGELOG
## v0.0.2 - _July 13, 2019_
* Dependencies updated
## v0.0.1 - _Invalid date_
* Create dev-utils package (#1848)
* Add `LibAssetData` and `LibTransactionDecoder` contracts (#1848)
* Refactor `LibAssetData` to only check 0x-specific allowances (#1848)
* Refactor `LibAssetData` balance/allowance checks to never revert (#1848)
* Refactor `OrderValidationUtils` to calculate `fillableTakerAssetAmount` (#1848)
* Add support for StaticCallProxy (#1863)

View File

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

View File

@@ -0,0 +1,73 @@
## Dev-Utils
This package implements various utilities for developers. For example, the `DevUtils` contract can query batches of balances or allowances given some `assetData`, can validate batches of orders, and can decode 0x-specific calldata. Addresses of the deployed contracts can be found in the 0x [wiki](https://0xproject.com/wiki#Deployed-Addresses) or the [DEPLOYS](./DEPLOYS.json) file within this package.
## Installation
**Install**
```bash
npm install @0x/contracts-dev-utils --save
```
## Bug bounty
A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0xproject.com/wiki#Bug-Bounty).
## Contributing
We strongly recommend that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository.
For proposals regarding the 0x protocol's smart contract architecture, message format, or additional functionality, go to the [0x Improvement Proposals (ZEIPs)](https://github.com/0xProject/ZEIPs) repository and follow the contribution guidelines provided therein.
Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
### Install Dependencies
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
```bash
yarn config set workspaces-experimental true
```
Then install dependencies
```bash
yarn install
```
### Build
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
PKG=@0x/contracts-extensions yarn build
```
Or continuously rebuild on change:
```bash
PKG=@0x/contracts-extensions yarn watch
```
### Clean
```bash
yarn clean
```
### Lint
```bash
yarn lint
```
### Run Tests
```bash
yarn test
```
#### Testing options
Contracts testing options like coverage, profiling, revert traces or backing node choosing - are described [here](../TESTING.md).

View File

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

View File

@@ -17,21 +17,21 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
pragma experimental ABIEncoderV2;
import "../src/libs/LibConstants.sol";
import "../src/MixinSignatureValidator.sol";
import "../src/MixinCoordinatorApprovalVerifier.sol";
import "./OrderValidationUtils.sol";
import "./LibTransactionDecoder.sol";
import "./EthBalanceChecker.sol";
// solhint-disable no-empty-blocks
contract TestMixins is
LibConstants,
MixinSignatureValidator,
MixinCoordinatorApprovalVerifier
contract DevUtils is
OrderValidationUtils,
LibTransactionDecoder,
EthBalanceChecker
{
constructor (address _exchange)
constructor (address _exchange, bytes memory _zrxAssetData)
public
LibConstants(_exchange)
OrderValidationUtils(_exchange, _zrxAssetData)
{}
}

View File

@@ -0,0 +1,39 @@
/*
Copyright 2018 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.5;
contract EthBalanceChecker {
/// @dev Batch fetches ETH balances
/// @param addresses Array of addresses.
/// @return Array of ETH balances.
function getEthBalances(address[] memory addresses)
public
view
returns (uint256[] memory)
{
uint256[] memory balances = new uint256[](addresses.length);
for (uint256 i = 0; i != addresses.length; i++) {
balances[i] = addresses[i].balance;
}
return balances;
}
}

View File

@@ -0,0 +1,541 @@
/*
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.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-asset-proxy/contracts/src/libs/LibAssetProxyIds.sol";
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
contract LibAssetData is
LibAssetProxyIds
{
// 2^256 - 1
uint256 constant internal _MAX_UINT256 = uint256(-1);
// ERC20 selectors
bytes4 constant internal _ERC20_BALANCE_OF_SELECTOR = 0x70a08231;
bytes4 constant internal _ERC20_ALLOWANCE_SELECTOR = 0xdd62ed3e;
// ERC721 selectors
bytes4 constant internal _ERC721_OWNER_OF_SELECTOR = 0x6352211e;
bytes4 constant internal _ERC721_IS_APPROVED_FOR_ALL_SELECTOR = 0xe985e9c5;
bytes4 constant internal _ERC721_GET_APPROVED_SELECTOR = 0x081812fc;
// ERC1155 selectors
bytes4 constant internal _ERC1155_BALANCE_OF_SELECTOR = 0x00fdd58e;
bytes4 constant internal _ERC1155_IS_APPROVED_FOR_ALL_SELECTOR = 0xe985e9c5;
// `transferFrom` selector for all AssetProxy contracts
bytes4 constant internal _ASSET_PROXY_TRANSFER_FROM_SELECTOR = 0xa85e59e4;
using LibBytes for bytes;
// solhint-disable var-name-mixedcase
IExchange internal _EXCHANGE;
address internal _ERC20_PROXY_ADDRESS;
address internal _ERC721_PROXY_ADDRESS;
address internal _ERC1155_PROXY_ADDRESS;
address internal _STATIC_CALL_PROXY_ADDRESS;
// solhint-enable var-name-mixedcase
constructor (address _exchange)
public
{
_EXCHANGE = IExchange(_exchange);
_ERC20_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC20_PROXY_ID);
_ERC721_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC721_PROXY_ID);
_ERC1155_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC1155_PROXY_ID);
_STATIC_CALL_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(STATIC_CALL_PROXY_ID);
}
/// @dev Returns the owner's balance of the assets(s) specified in
/// assetData. When the asset data contains multiple assets (eg in
/// ERC1155 or Multi-Asset), the return value indicates how many
/// complete "baskets" of those assets are owned by owner.
/// @param ownerAddress Owner of the assets specified by assetData.
/// @param assetData Details of asset, encoded per the AssetProxy contract specification.
/// @return Number of assets (or asset baskets) held by owner.
function getBalance(address ownerAddress, bytes memory assetData)
public
view
returns (uint256 balance)
{
// Get id of AssetProxy contract
bytes4 assetProxyId = assetData.readBytes4(0);
if (assetProxyId == ERC20_PROXY_ID) {
// Get ERC20 token address
address tokenAddress = assetData.readAddress(16);
// Encode data for `balanceOf(ownerAddress)`
bytes memory balanceOfData = abi.encodeWithSelector(_ERC20_BALANCE_OF_SELECTOR, ownerAddress);
// Query balance
(bool success, bytes memory returnData) = tokenAddress.staticcall(balanceOfData);
balance = success && returnData.length == 32 ? returnData.readUint256(0) : 0;
} else if (assetProxyId == ERC721_PROXY_ID) {
// Get ERC721 token address and id
(, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData);
// Check if id is owned by ownerAddress
balance = getERC721TokenOwner(tokenAddress, tokenId) == ownerAddress ? 1 : 0;
} else if (assetProxyId == ERC1155_PROXY_ID) {
// Get ERC1155 token address, array of ids, and array of values
(, address tokenAddress, uint256[] memory tokenIds, uint256[] memory tokenValues,) = decodeERC1155AssetData(assetData);
uint256 length = tokenIds.length;
for (uint256 i = 0; i != length; i++) {
// Encode data for `balanceOf(ownerAddress, tokenIds[i])
bytes memory balanceOfData = abi.encodeWithSelector(
_ERC1155_BALANCE_OF_SELECTOR,
ownerAddress,
tokenIds[i]
);
// Query balance
(bool success, bytes memory returnData) = tokenAddress.staticcall(balanceOfData);
uint256 totalBalance = success && returnData.length == 32 ? returnData.readUint256(0) : 0;
// Scale total balance down by corresponding value in assetData
uint256 scaledBalance = totalBalance / tokenValues[i];
if (scaledBalance < balance || balance == 0) {
balance = scaledBalance;
}
}
} else if (assetProxyId == STATIC_CALL_PROXY_ID) {
// Encode data for `staticCallProxy.transferFrom(assetData,...)`
bytes memory transferFromData = abi.encodeWithSelector(
_ASSET_PROXY_TRANSFER_FROM_SELECTOR,
assetData,
address(0), // `from` address is not used
address(0), // `to` address is not used
0 // `amount` is not used
);
// Check if staticcall would be successful
(bool success,) = _STATIC_CALL_PROXY_ADDRESS.staticcall(transferFromData);
// Success means that the staticcall can be made an unlimited amount of times
balance = success ? _MAX_UINT256 : 0;
} else if (assetProxyId == MULTI_ASSET_PROXY_ID) {
// Get array of values and array of assetDatas
(, uint256[] memory assetAmounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData);
uint256 length = nestedAssetData.length;
for (uint256 i = 0; i != length; i++) {
// Query balance of individual assetData
uint256 totalBalance = getBalance(ownerAddress, nestedAssetData[i]);
// Scale total balance down by corresponding value in assetData
uint256 scaledBalance = totalBalance / assetAmounts[i];
if (scaledBalance < balance || balance == 0) {
balance = scaledBalance;
}
}
}
// Balance will be 0 if assetProxyId is unknown
return balance;
}
/// @dev Calls getBalance() for each element of assetData.
/// @param ownerAddress Owner of the assets specified by assetData.
/// @param assetData Array of asset details, each encoded per the AssetProxy contract specification.
/// @return Array of asset balances from getBalance(), with each element
/// corresponding to the same-indexed element in the assetData input.
function getBatchBalances(address ownerAddress, bytes[] memory assetData)
public
view
returns (uint256[] memory balances)
{
uint256 length = assetData.length;
balances = new uint256[](length);
for (uint256 i = 0; i != length; i++) {
balances[i] = getBalance(ownerAddress, assetData[i]);
}
return balances;
}
/// @dev Returns the number of asset(s) (described by assetData) that
/// the corresponding AssetProxy contract is authorized to spend. When the asset data contains
/// multiple assets (eg for Multi-Asset), the return value indicates
/// how many complete "baskets" of those assets may be spent by all of the corresponding
/// AssetProxy contracts.
/// @param ownerAddress Owner of the assets specified by assetData.
/// @param assetData Details of asset, encoded per the AssetProxy contract specification.
/// @return Number of assets (or asset baskets) that the corresponding AssetProxy is authorized to spend.
function getAssetProxyAllowance(address ownerAddress, bytes memory assetData)
public
view
returns (uint256 allowance)
{
// Get id of AssetProxy contract
bytes4 assetProxyId = assetData.readBytes4(0);
if (assetProxyId == MULTI_ASSET_PROXY_ID) {
// Get array of values and array of assetDatas
(, uint256[] memory amounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData);
uint256 length = nestedAssetData.length;
for (uint256 i = 0; i != length; i++) {
// Query allowance of individual assetData
uint256 totalAllowance = getAssetProxyAllowance(ownerAddress, nestedAssetData[i]);
// Scale total allowance down by corresponding value in assetData
uint256 scaledAllowance = totalAllowance / amounts[i];
if (scaledAllowance < allowance || allowance == 0) {
allowance = scaledAllowance;
}
}
return allowance;
}
if (assetProxyId == ERC20_PROXY_ID) {
// Get ERC20 token address
address tokenAddress = assetData.readAddress(16);
// Encode data for `allowance(ownerAddress, _ERC20_PROXY_ADDRESS)`
bytes memory allowanceData = abi.encodeWithSelector(
_ERC20_ALLOWANCE_SELECTOR,
ownerAddress,
_ERC20_PROXY_ADDRESS
);
// Query allowance
(bool success, bytes memory returnData) = tokenAddress.staticcall(allowanceData);
allowance = success && returnData.length == 32 ? returnData.readUint256(0) : 0;
} else if (assetProxyId == ERC721_PROXY_ID) {
// Get ERC721 token address and id
(, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData);
// Encode data for `isApprovedForAll(ownerAddress, _ERC721_PROXY_ADDRESS)`
bytes memory isApprovedForAllData = abi.encodeWithSelector(
_ERC721_IS_APPROVED_FOR_ALL_SELECTOR,
ownerAddress,
_ERC721_PROXY_ADDRESS
);
(bool success, bytes memory returnData) = tokenAddress.staticcall(isApprovedForAllData);
// If not approved for all, call `getApproved(tokenId)`
if (!success || returnData.length != 32 || returnData.readUint256(0) != 1) {
// Encode data for `getApproved(tokenId)`
bytes memory getApprovedData = abi.encodeWithSelector(_ERC721_GET_APPROVED_SELECTOR, tokenId);
(success, returnData) = tokenAddress.staticcall(getApprovedData);
// Allowance is 1 if successful and the approved address is the ERC721Proxy
allowance = success && returnData.length == 32 && returnData.readAddress(12) == _ERC721_PROXY_ADDRESS ? 1 : 0;
} else {
// Allowance is 2^256 - 1 if `isApprovedForAll` returned true
allowance = _MAX_UINT256;
}
} else if (assetProxyId == ERC1155_PROXY_ID) {
// Get ERC1155 token address
(, address tokenAddress, , , ) = decodeERC1155AssetData(assetData);
// Encode data for `isApprovedForAll(ownerAddress, _ERC1155_PROXY_ADDRESS)`
bytes memory isApprovedForAllData = abi.encodeWithSelector(
_ERC1155_IS_APPROVED_FOR_ALL_SELECTOR,
ownerAddress,
_ERC1155_PROXY_ADDRESS
);
// Query allowance
(bool success, bytes memory returnData) = tokenAddress.staticcall(isApprovedForAllData);
allowance = success && returnData.length == 32 && returnData.readUint256(0) == 1 ? _MAX_UINT256 : 0;
} else if (assetProxyId == STATIC_CALL_PROXY_ID) {
// The StaticCallProxy does not require any approvals
allowance = _MAX_UINT256;
}
// Allowance will be 0 if the assetProxyId is unknown
return allowance;
}
/// @dev Calls getAssetProxyAllowance() for each element of assetData.
/// @param ownerAddress Owner of the assets specified by assetData.
/// @param assetData Array of asset details, each encoded per the AssetProxy contract specification.
/// @return An array of asset allowances from getAllowance(), with each
/// element corresponding to the same-indexed element in the assetData input.
function getBatchAssetProxyAllowances(address ownerAddress, bytes[] memory assetData)
public
view
returns (uint256[] memory allowances)
{
uint256 length = assetData.length;
allowances = new uint256[](length);
for (uint256 i = 0; i != length; i++) {
allowances[i] = getAssetProxyAllowance(ownerAddress, assetData[i]);
}
return allowances;
}
/// @dev Calls getBalance() and getAllowance() for assetData.
/// @param ownerAddress Owner of the assets specified by assetData.
/// @param assetData Details of asset, encoded per the AssetProxy contract specification.
/// @return Number of assets (or asset baskets) held by owner, and number
/// of assets (or asset baskets) that the corresponding AssetProxy is authorized to spend.
function getBalanceAndAssetProxyAllowance(address ownerAddress, bytes memory assetData)
public
view
returns (uint256 balance, uint256 allowance)
{
balance = getBalance(ownerAddress, assetData);
allowance = getAssetProxyAllowance(ownerAddress, assetData);
return (balance, allowance);
}
/// @dev Calls getBatchBalances() and getBatchAllowances() for each element of assetData.
/// @param ownerAddress Owner of the assets specified by assetData.
/// @param assetData Array of asset details, each encoded per the AssetProxy contract specification.
/// @return An array of asset balances from getBalance(), and an array of
/// asset allowances from getAllowance(), with each element
/// corresponding to the same-indexed element in the assetData input.
function getBatchBalancesAndAssetProxyAllowances(address ownerAddress, bytes[] memory assetData)
public
view
returns (uint256[] memory balances, uint256[] memory allowances)
{
balances = getBatchBalances(ownerAddress, assetData);
allowances = getBatchAssetProxyAllowances(ownerAddress, assetData);
return (balances, allowances);
}
/// @dev Encode ERC-20 asset data into the format described in the AssetProxy contract specification.
/// @param tokenAddress The address of the ERC-20 contract hosting the asset to be traded.
/// @return AssetProxy-compliant data describing the asset.
function encodeERC20AssetData(address tokenAddress)
public
pure
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(ERC20_PROXY_ID, tokenAddress);
return assetData;
}
/// @dev Decode ERC-20 asset data from the format described in the AssetProxy contract specification.
/// @param assetData AssetProxy-compliant asset data describing an ERC-20 asset.
/// @return The ERC-20 AssetProxy identifier, and the address of the ERC-20
/// contract hosting this asset.
function decodeERC20AssetData(bytes memory assetData)
public
pure
returns (
bytes4 assetProxyId,
address tokenAddress
)
{
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC20_PROXY_ID,
"WRONG_PROXY_ID"
);
tokenAddress = assetData.readAddress(16);
return (assetProxyId, tokenAddress);
}
/// @dev Encode ERC-721 asset data into the format described in the AssetProxy specification.
/// @param tokenAddress The address of the ERC-721 contract hosting the asset to be traded.
/// @param tokenId The identifier of the specific asset to be traded.
/// @return AssetProxy-compliant asset data describing the asset.
function encodeERC721AssetData(address tokenAddress, uint256 tokenId)
public
pure
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
ERC721_PROXY_ID,
tokenAddress,
tokenId
);
return assetData;
}
/// @dev Decode ERC-721 asset data from the format described in the AssetProxy contract specification.
/// @param assetData AssetProxy-compliant asset data describing an ERC-721 asset.
/// @return The ERC-721 AssetProxy identifier, the address of the ERC-721
/// contract hosting this asset, and the identifier of the specific
/// asset to be traded.
function decodeERC721AssetData(bytes memory assetData)
public
pure
returns (
bytes4 assetProxyId,
address tokenAddress,
uint256 tokenId
)
{
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC721_PROXY_ID,
"WRONG_PROXY_ID"
);
tokenAddress = assetData.readAddress(16);
tokenId = assetData.readUint256(36);
return (assetProxyId, tokenAddress, tokenId);
}
/// @dev Encode ERC-1155 asset data into the format described in the AssetProxy contract specification.
/// @param tokenAddress The address of the ERC-1155 contract hosting the asset(s) to be traded.
/// @param tokenIds The identifiers of the specific assets to be traded.
/// @param tokenValues The amounts of each asset to be traded.
/// @param callbackData Data to be passed to receiving contracts when a transfer is performed.
/// @return AssetProxy-compliant asset data describing the set of assets.
function encodeERC1155AssetData(
address tokenAddress,
uint256[] memory tokenIds,
uint256[] memory tokenValues,
bytes memory callbackData
)
public
pure
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
ERC1155_PROXY_ID,
tokenAddress,
tokenIds,
tokenValues,
callbackData
);
return assetData;
}
/// @dev Decode ERC-1155 asset data from the format described in the AssetProxy contract specification.
/// @param assetData AssetProxy-compliant asset data describing an ERC-1155 set of assets.
/// @return The ERC-1155 AssetProxy identifier, the address of the ERC-1155
/// contract hosting the assets, an array of the identifiers of the
/// assets to be traded, an array of asset amounts to be traded, and
/// callback data. Each element of the arrays corresponds to the
/// same-indexed element of the other array. Return values specified as
/// `memory` are returned as pointers to locations within the memory of
/// the input parameter `assetData`.
function decodeERC1155AssetData(bytes memory assetData)
public
pure
returns (
bytes4 assetProxyId,
address tokenAddress,
uint256[] memory tokenIds,
uint256[] memory tokenValues,
bytes memory callbackData
)
{
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC1155_PROXY_ID,
"WRONG_PROXY_ID"
);
assembly {
// Skip selector and length to get to the first parameter:
assetData := add(assetData, 36)
// Read the value of the first parameter:
tokenAddress := mload(assetData)
// Point to the next parameter's data:
tokenIds := add(assetData, mload(add(assetData, 32)))
// Point to the next parameter's data:
tokenValues := add(assetData, mload(add(assetData, 64)))
// Point to the next parameter's data:
callbackData := add(assetData, mload(add(assetData, 96)))
}
return (
assetProxyId,
tokenAddress,
tokenIds,
tokenValues,
callbackData
);
}
/// @dev Encode data for multiple assets, per the AssetProxy contract specification.
/// @param amounts The amounts of each asset to be traded.
/// @param nestedAssetData AssetProxy-compliant data describing each asset to be traded.
/// @return AssetProxy-compliant data describing the set of assets.
function encodeMultiAssetData(uint256[] memory amounts, bytes[] memory nestedAssetData)
public
pure
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
MULTI_ASSET_PROXY_ID,
amounts,
nestedAssetData
);
return assetData;
}
/// @dev Decode multi-asset data from the format described in the AssetProxy contract specification.
/// @param assetData AssetProxy-compliant data describing a multi-asset basket.
/// @return The Multi-Asset AssetProxy identifier, an array of the amounts
/// of the assets to be traded, and an array of the
/// AssetProxy-compliant data describing each asset to be traded. Each
/// element of the arrays corresponds to the same-indexed element of the other array.
function decodeMultiAssetData(bytes memory assetData)
public
pure
returns (
bytes4 assetProxyId,
uint256[] memory amounts,
bytes[] memory nestedAssetData
)
{
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == MULTI_ASSET_PROXY_ID,
"WRONG_PROXY_ID"
);
// solhint-disable indent
(amounts, nestedAssetData) = abi.decode(
assetData.slice(4, assetData.length),
(uint256[], bytes[])
);
// solhint-enable indent
}
/// @dev Calls `asset.ownerOf(tokenId)`, but returns a null owner instead of reverting on an unowned asset.
/// @param tokenAddress Address of ERC721 asset.
/// @param tokenId The identifier for the specific NFT.
/// @return Owner of tokenId or null address if unowned.
function getERC721TokenOwner(address tokenAddress, uint256 tokenId)
public
view
returns (address ownerAddress)
{
bytes memory ownerOfCalldata = abi.encodeWithSelector(
_ERC721_OWNER_OF_SELECTOR,
tokenId
);
(bool success, bytes memory returnData) = tokenAddress.staticcall(ownerOfCalldata);
ownerAddress = (success && returnData.length == 32) ? returnData.readAddress(12) : address(0);
return ownerAddress;
}
}

View File

@@ -0,0 +1,193 @@
/*
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.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange-libs/contracts/src/LibExchangeSelectors.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
contract LibTransactionDecoder is
LibExchangeSelectors
{
using LibBytes for bytes;
/// @dev Decodes the call data for an Exchange contract method call.
/// @param transactionData ABI-encoded calldata for an Exchange
/// contract method call.
/// @return The name of the function called, and the parameters it was
/// given. For single-order fills and cancels, the arrays will have
/// just one element.
function decodeZeroExTransactionData(bytes memory transactionData)
public
pure
returns(
string memory functionName,
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures
)
{
bytes4 functionSelector = transactionData.readBytes4(0);
if (functionSelector == BATCH_CANCEL_ORDERS_SELECTOR) {
functionName = "batchCancelOrders";
} else if (functionSelector == BATCH_FILL_ORDERS_SELECTOR) {
functionName = "batchFillOrders";
} else if (functionSelector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR) {
functionName = "batchFillOrdersNoThrow";
} else if (functionSelector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR) {
functionName = "batchFillOrKillOrders";
} else if (functionSelector == CANCEL_ORDER_SELECTOR) {
functionName = "cancelOrder";
} else if (functionSelector == FILL_ORDER_SELECTOR) {
functionName = "fillOrder";
} else if (functionSelector == FILL_ORDER_NO_THROW_SELECTOR) {
functionName = "fillOrderNoThrow";
} else if (functionSelector == FILL_OR_KILL_ORDER_SELECTOR) {
functionName = "fillOrKillOrder";
} else if (functionSelector == MARKET_BUY_ORDERS_SELECTOR) {
functionName = "marketBuyOrders";
} else if (functionSelector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR) {
functionName = "marketBuyOrdersNoThrow";
} else if (functionSelector == MARKET_SELL_ORDERS_SELECTOR) {
functionName = "marketSellOrders";
} else if (functionSelector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR) {
functionName = "marketSellOrdersNoThrow";
} else if (functionSelector == MATCH_ORDERS_SELECTOR) {
functionName = "matchOrders";
} else if (
functionSelector == CANCEL_ORDERS_UP_TO_SELECTOR ||
functionSelector == EXECUTE_TRANSACTION_SELECTOR
// TODO: add new noThrow cancel functions when https://github.com/0xProject/ZEIPs/issues/35 is merged.
) {
revert("UNIMPLEMENTED");
} else {
revert("UNKNOWN_FUNCTION_SELECTOR");
}
if (functionSelector == BATCH_CANCEL_ORDERS_SELECTOR) {
// solhint-disable-next-line indent
orders = abi.decode(transactionData.slice(4, transactionData.length), (LibOrder.Order[]));
takerAssetFillAmounts = new uint256[](0);
signatures = new bytes[](0);
} else if (
functionSelector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR ||
functionSelector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR ||
functionSelector == BATCH_FILL_ORDERS_SELECTOR
) {
(orders, takerAssetFillAmounts, signatures) = _makeReturnValuesForBatchFill(transactionData);
} else if (functionSelector == CANCEL_ORDER_SELECTOR) {
orders = new LibOrder.Order[](1);
orders[0] = abi.decode(transactionData.slice(4, transactionData.length), (LibOrder.Order));
takerAssetFillAmounts = new uint256[](0);
signatures = new bytes[](0);
} else if (
functionSelector == FILL_OR_KILL_ORDER_SELECTOR ||
functionSelector == FILL_ORDER_SELECTOR ||
functionSelector == FILL_ORDER_NO_THROW_SELECTOR
) {
(orders, takerAssetFillAmounts, signatures) = _makeReturnValuesForSingleOrderFill(transactionData);
} else if (
functionSelector == MARKET_BUY_ORDERS_SELECTOR ||
functionSelector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR ||
functionSelector == MARKET_SELL_ORDERS_SELECTOR ||
functionSelector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR
) {
(orders, takerAssetFillAmounts, signatures) = _makeReturnValuesForMarketFill(transactionData);
} else if (functionSelector == MATCH_ORDERS_SELECTOR) {
(
LibOrder.Order memory leftOrder,
LibOrder.Order memory rightOrder,
bytes memory leftSignature,
bytes memory rightSignature
) = abi.decode(
transactionData.slice(4, transactionData.length),
(LibOrder.Order, LibOrder.Order, bytes, bytes)
);
orders = new LibOrder.Order[](2);
orders[0] = leftOrder;
orders[1] = rightOrder;
takerAssetFillAmounts = new uint256[](2);
takerAssetFillAmounts[0] = leftOrder.takerAssetAmount;
takerAssetFillAmounts[1] = rightOrder.takerAssetAmount;
signatures = new bytes[](2);
signatures[0] = leftSignature;
signatures[1] = rightSignature;
}
}
function _makeReturnValuesForSingleOrderFill(bytes memory transactionData)
private
pure
returns(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures
)
{
orders = new LibOrder.Order[](1);
takerAssetFillAmounts = new uint256[](1);
signatures = new bytes[](1);
// solhint-disable-next-line indent
(orders[0], takerAssetFillAmounts[0], signatures[0]) = abi.decode(
transactionData.slice(4, transactionData.length),
(LibOrder.Order, uint256, bytes)
);
}
function _makeReturnValuesForBatchFill(bytes memory transactionData)
private
pure
returns(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures
)
{
// solhint-disable-next-line indent
(orders, takerAssetFillAmounts, signatures) = abi.decode(
transactionData.slice(4, transactionData.length),
// solhint-disable-next-line indent
(LibOrder.Order[], uint256[], bytes[])
);
}
function _makeReturnValuesForMarketFill(bytes memory transactionData)
private
pure
returns(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures
)
{
takerAssetFillAmounts = new uint256[](1);
// solhint-disable-next-line indent
(orders, takerAssetFillAmounts[0], signatures) = abi.decode(
transactionData.slice(4, transactionData.length),
// solhint-disable-next-line indent
(LibOrder.Order[], uint256, bytes[])
);
}
}

View File

@@ -0,0 +1,184 @@
/*
Copyright 2018 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.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "./LibAssetData.sol";
contract OrderValidationUtils is
LibAssetData,
LibMath
{
using LibBytes for bytes;
// solhint-disable var-name-mixedcase
bytes internal _ZRX_ASSET_DATA;
// solhint-enable var-name-mixedcase
constructor (address _exchange, bytes memory _zrxAssetData)
public
LibAssetData(_exchange)
{
_ZRX_ASSET_DATA = _zrxAssetData;
}
/// @dev Fetches all order-relevant information needed to validate if the supplied order is fillable.
/// @param order The order structure.
/// @param signature Signature provided by maker that proves the order's authenticity.
/// `0x01` can always be provided if the signature does not need to be validated.
/// @return The orderInfo (hash, status, and `takerAssetAmount` already filled for the given order),
/// fillableTakerAssetAmount (amount of the order's `takerAssetAmount` that is fillable given all on-chain state),
/// and isValidSignature (validity of the provided signature).
/// NOTE: If the `takerAssetData` encodes data for multiple assets, `fillableTakerAssetAmount` will represent a "scaled"
/// amount, meaning it must be multiplied by all the individual asset amounts within the `takerAssetData` to get the final
/// amount of each asset that can be filled.
function getOrderRelevantState(LibOrder.Order memory order, bytes memory signature)
public
view
returns (
LibOrder.OrderInfo memory orderInfo,
uint256 fillableTakerAssetAmount,
bool isValidSignature
)
{
// Get info specific to order
orderInfo = _EXCHANGE.getOrderInfo(order);
// Validate the maker's signature
address makerAddress = order.makerAddress;
isValidSignature = _EXCHANGE.isValidSignature(
orderInfo.orderHash,
makerAddress,
signature
);
// Get the transferable amount of the `makerAsset`
uint256 transferableMakerAssetAmount = getTransferableAssetAmount(makerAddress, order.makerAssetData);
// Assign to stack variables to reduce redundant mloads/sloads
uint256 takerAssetAmount = order.takerAssetAmount;
uint256 makerFee = order.makerFee;
bytes memory zrxAssetData = _ZRX_ASSET_DATA;
// Get the amount of `takerAsset` that is transferable to maker given the transferability of `makerAsset`, `makerFeeAsset`,
// and the total amounts specified in the order
uint256 transferableTakerAssetAmount;
if (order.makerAssetData.equals(zrxAssetData)) {
// If `makerAsset` equals `makerFeeAsset`, the % that can be filled is
// transferableMakerAssetAmount / (makerAssetAmount + makerFee)
transferableTakerAssetAmount = getPartialAmountFloor(
transferableMakerAssetAmount,
safeAdd(order.makerAssetAmount, makerFee),
takerAssetAmount
);
} else {
// Get the transferable amount of the `makerFeeAsset`
uint256 transferableMakerFeeAssetAmount = getTransferableAssetAmount(makerAddress, zrxAssetData);
// If `makerFee` is 0, the % that can be filled is (transferableMakerAssetAmount / makerAssetAmount)
if (makerFee == 0) {
transferableTakerAssetAmount = getPartialAmountFloor(
transferableMakerAssetAmount,
order.makerAssetAmount,
takerAssetAmount
);
// If `makerAsset` does not equal `makerFeeAsset`, the % that can be filled is the lower of
// (transferableMakerAssetAmount / makerAssetAmount) and (transferableMakerAssetFeeAmount / makerFee)
} else {
uint256 transferableMakerToTakerAmount = getPartialAmountFloor(
transferableMakerAssetAmount,
order.makerAssetAmount,
takerAssetAmount
);
uint256 transferableMakerFeeToTakerAmount = getPartialAmountFloor(
transferableMakerFeeAssetAmount,
makerFee,
takerAssetAmount
);
transferableTakerAssetAmount = min256(transferableMakerToTakerAmount, transferableMakerFeeToTakerAmount);
}
}
// `fillableTakerAssetAmount` is the lower of the order's remaining `takerAssetAmount` and the `transferableTakerAssetAmount`
fillableTakerAssetAmount = min256(
safeSub(takerAssetAmount, orderInfo.orderTakerAssetFilledAmount),
transferableTakerAssetAmount
);
return (orderInfo, fillableTakerAssetAmount, isValidSignature);
}
/// @dev Fetches all order-relevant information needed to validate if the supplied orders are fillable.
/// @param orders Array of order structures.
/// @param signatures Array of signatures provided by makers that prove the authenticity of the orders.
/// `0x01` can always be provided if a signature does not need to be validated.
/// @return The ordersInfo (array of the hash, status, and `takerAssetAmount` already filled for each order),
/// fillableTakerAssetAmounts (array of amounts for each order's `takerAssetAmount` that is fillable given all on-chain state),
/// and isValidSignature (array containing the validity of each provided signature).
/// NOTE: If the `takerAssetData` encodes data for multiple assets, each element of `fillableTakerAssetAmounts`
/// will represent a "scaled" amount, meaning it must be multiplied by all the individual asset amounts within
/// the `takerAssetData` to get the final amount of each asset that can be filled.
function getOrderRelevantStates(LibOrder.Order[] memory orders, bytes[] memory signatures)
public
view
returns (
LibOrder.OrderInfo[] memory ordersInfo,
uint256[] memory fillableTakerAssetAmounts,
bool[] memory isValidSignature
)
{
uint256 length = orders.length;
ordersInfo = new LibOrder.OrderInfo[](length);
fillableTakerAssetAmounts = new uint256[](length);
isValidSignature = new bool[](length);
for (uint256 i = 0; i != length; i++) {
(ordersInfo[i], fillableTakerAssetAmounts[i], isValidSignature[i]) = getOrderRelevantState(
orders[i],
signatures[i]
);
}
return (ordersInfo, fillableTakerAssetAmounts, isValidSignature);
}
/// @dev Gets the amount of an asset transferable by the owner.
/// @param ownerAddress Address of the owner of the asset.
/// @param assetData Description of tokens, per the AssetProxy contract specification.
/// @return The amount of the asset tranferable by the owner.
/// NOTE: If the `assetData` encodes data for multiple assets, the `transferableAssetAmount`
/// will represent the amount of times the entire `assetData` can be transferred. To calculate
/// the total individual transferable amounts, this scaled `transferableAmount` must be multiplied by
/// the individual asset amounts located within the `assetData`.
function getTransferableAssetAmount(address ownerAddress, bytes memory assetData)
public
view
returns (uint256 transferableAssetAmount)
{
(uint256 balance, uint256 allowance) = getBalanceAndAssetProxyAllowance(ownerAddress, assetData);
transferableAssetAmount = min256(balance, allowance);
return transferableAssetAmount;
}
}

View File

@@ -0,0 +1,91 @@
{
"name": "@0x/contracts-dev-utils",
"version": "0.0.2",
"engines": {
"node": ">=6.12"
},
"description": "0x protocol specific utility contracts",
"main": "lib/src/index.js",
"directories": {
"test": "test"
},
"scripts": {
"build": "yarn pre_build && tsc -b",
"build:ci": "yarn build",
"pre_build": "run-s compile generate_contract_wrappers",
"test": "yarn run_mocha",
"rebuild_and_test": "run-s build test",
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile": "sol-compiler",
"watch": "sol-compiler -w",
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html",
"coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test",
"contracts:gen": "contracts-gen",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
},
"config": {
"abis": "./generated-artifacts/@(DevUtils|LibAssetData|LibTransactionDecoder|EthBalanceChecker).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
"type": "git",
"url": "https://github.com/0xProject/0x-monorepo.git"
},
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/0xProject/0x-monorepo/issues"
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/dev-utils/README.md",
"devDependencies": {
"@0x/abi-gen": "^2.1.0",
"@0x/contract-wrappers": "^9.1.5",
"@0x/contracts-gen": "^1.0.10",
"@0x/contracts-test-utils": "^3.1.8",
"@0x/dev-utils": "^2.2.4",
"@0x/sol-compiler": "^3.1.9",
"@0x/tslint-config": "^3.0.1",
"@types/lodash": "4.14.104",
"@types/node": "*",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"make-promises-safe": "^1.1.0",
"mocha": "^4.1.0",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"solhint": "^1.4.1",
"tslint": "5.11.0",
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.1.1",
"@0x/contracts-asset-proxy": "^2.2.0",
"@0x/contracts-erc1155": "^1.1.7",
"@0x/contracts-erc20": "^2.2.6",
"@0x/contracts-erc721": "^2.1.7",
"@0x/contracts-exchange": "^2.1.6",
"@0x/contracts-exchange-libs": "^3.0.0",
"@0x/contracts-utils": "^3.1.7",
"@0x/order-utils": "^8.2.0",
"@0x/types": "^2.4.0",
"@0x/typescript-typings": "^4.2.3",
"@0x/utils": "^4.4.0",
"@0x/web3-wrapper": "^6.0.7",
"ethereum-types": "^2.1.3",
"ethereumjs-util": "^5.1.1"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -0,0 +1,15 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
import { ContractArtifact } from 'ethereum-types';
import * as DevUtils from '../generated-artifacts/DevUtils.json';
import * as LibAssetData from '../generated-artifacts/LibAssetData.json';
import * as LibTransactionDecoder from '../generated-artifacts/LibTransactionDecoder.json';
export const artifacts = {
DevUtils: DevUtils as ContractArtifact,
LibTransactionDecoder: LibTransactionDecoder as ContractArtifact,
LibAssetData: LibAssetData as ContractArtifact,
};

View File

@@ -0,0 +1,2 @@
export * from './artifacts';
export * from './wrappers';

View File

@@ -0,0 +1,8 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
export * from '../generated-wrappers/dev_utils';
export * from '../generated-wrappers/lib_asset_data';
export * from '../generated-wrappers/lib_transaction_decoder';

View File

@@ -0,0 +1,19 @@
import { env, EnvVars } from '@0x/dev-utils';
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
import { providerUtils } from '@0x/utils';
before('start web3 provider', () => {
providerUtils.startProviderEngine(provider);
});
after('generate coverage report', async () => {
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
const coverageSubprovider = coverage.getCoverageSubproviderSingleton();
await coverageSubprovider.writeCoverageAsync();
}
if (env.parseBoolean(EnvVars.SolidityProfiler)) {
const profilerSubprovider = profiler.getProfilerSubproviderSingleton();
await profilerSubprovider.writeProfilerOutputAsync();
}
provider.stop();
});

View File

@@ -0,0 +1,527 @@
import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types';
import {
artifacts as proxyArtifacts,
ERC1155ProxyContract,
ERC20ProxyContract,
ERC721ProxyContract,
MultiAssetProxyContract,
StaticCallProxyContract,
TestStaticCallTargetContract,
} from '@0x/contracts-asset-proxy';
import {
artifacts as erc1155Artifacts,
ERC1155MintableContract,
ERC1155TransferSingleEventArgs,
} from '@0x/contracts-erc1155';
import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20';
import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/contracts-erc721';
import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange';
import { chaiSetup, constants, LogDecoder, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { assetDataUtils } from '@0x/order-utils';
import { AssetProxyId } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as ethUtil from 'ethereumjs-util';
import { artifacts, LibAssetDataContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const KNOWN_ERC20_ENCODING = {
address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
assetData: '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48',
};
const KNOWN_ERC721_ENCODING = {
address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
tokenId: new BigNumber(1),
assetData:
'0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001',
};
const KNOWN_ERC1155_ENCODING = {
tokenAddress: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
tokenIds: [new BigNumber(100), new BigNumber(1001), new BigNumber(10001)],
tokenValues: [new BigNumber(200), new BigNumber(2001), new BigNumber(20001)],
callbackData:
'0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001',
assetData:
'0xa7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000',
};
const KNOWN_MULTI_ASSET_ENCODING = {
amounts: [new BigNumber(70), new BigNumber(1), new BigNumber(18)],
nestedAssetData: [
KNOWN_ERC20_ENCODING.assetData,
KNOWN_ERC721_ENCODING.assetData,
KNOWN_ERC1155_ENCODING.assetData,
],
assetData:
'0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204a7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
};
describe('LibAssetData', () => {
let exchange: ExchangeContract;
let erc20Proxy: ERC20ProxyContract;
let erc721Proxy: ERC721ProxyContract;
let erc1155Proxy: ERC1155ProxyContract;
let multiAssetProxy: MultiAssetProxyContract;
let staticCallProxy: StaticCallProxyContract;
let staticCallTarget: TestStaticCallTargetContract;
let libAssetData: LibAssetDataContract;
let tokenOwnerAddress: string;
let erc20Token: DummyERC20TokenContract;
let erc721Token: DummyERC721TokenContract;
let erc1155Token: ERC1155MintableContract;
const erc20TokenTotalSupply = new BigNumber(1);
const firstERC721TokenId = new BigNumber(1);
const numberOfERC721Tokens = 10;
let erc1155TokenId: BigNumber;
before(async () => {
await blockchainLifecycle.startAsync();
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
exchangeArtifacts.Exchange,
provider,
txDefaults,
constants.NULL_BYTES,
);
erc20Proxy = await ERC20ProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.ERC20Proxy,
provider,
txDefaults,
);
erc721Proxy = await ERC721ProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.ERC721Proxy,
provider,
txDefaults,
);
erc1155Proxy = await ERC1155ProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.ERC1155Proxy,
provider,
txDefaults,
);
multiAssetProxy = await MultiAssetProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.MultiAssetProxy,
provider,
txDefaults,
);
staticCallProxy = await StaticCallProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.StaticCallProxy,
provider,
txDefaults,
);
await exchange.registerAssetProxy.awaitTransactionSuccessAsync(erc20Proxy.address);
await exchange.registerAssetProxy.awaitTransactionSuccessAsync(erc721Proxy.address);
await exchange.registerAssetProxy.awaitTransactionSuccessAsync(erc1155Proxy.address);
await exchange.registerAssetProxy.awaitTransactionSuccessAsync(multiAssetProxy.address);
await exchange.registerAssetProxy.awaitTransactionSuccessAsync(staticCallProxy.address);
libAssetData = await LibAssetDataContract.deployFrom0xArtifactAsync(
artifacts.LibAssetData,
provider,
txDefaults,
exchange.address,
);
staticCallTarget = await TestStaticCallTargetContract.deployFrom0xArtifactAsync(
proxyArtifacts.TestStaticCallTarget,
provider,
txDefaults,
);
[tokenOwnerAddress] = await web3Wrapper.getAvailableAddressesAsync();
erc20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
erc20Artifacts.DummyERC20Token,
provider,
txDefaults,
'Dummy',
'DUM',
new BigNumber(1),
erc20TokenTotalSupply,
);
erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync(
erc721Artifacts.DummyERC721Token,
provider,
txDefaults,
'Dummy',
'DUM',
);
// mint `numberOfERC721Tokens` tokens
const transactionMinedPromises = [];
for (let i = 0; i < numberOfERC721Tokens; i++) {
transactionMinedPromises.push(
erc721Token.mint.awaitTransactionSuccessAsync(tokenOwnerAddress, firstERC721TokenId.plus(i - 1)),
);
}
await Promise.all(transactionMinedPromises);
erc1155Token = await ERC1155MintableContract.deployFrom0xArtifactAsync(
erc1155Artifacts.ERC1155Mintable,
provider,
txDefaults,
);
const logDecoder = new LogDecoder(web3Wrapper, erc1155Artifacts);
const transactionReceipt = await logDecoder.getTxWithDecodedLogsAsync(
await erc1155Token.create.sendTransactionAsync('uri:Dummy', /*isNonFungible:*/ false),
);
// tslint:disable-next-line no-unnecessary-type-assertion
erc1155TokenId = (transactionReceipt.logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>).args.id;
await erc1155Token.mintFungible.awaitTransactionSuccessAsync(
erc1155TokenId,
[tokenOwnerAddress],
[new BigNumber(1)],
);
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
it('should have a deployed-to address', () => {
expect(libAssetData.address.slice(0, 2)).to.equal('0x');
});
describe('encoding and decoding', () => {
it('should encode ERC20 asset data', async () => {
expect(await libAssetData.encodeERC20AssetData.callAsync(KNOWN_ERC20_ENCODING.address)).to.equal(
KNOWN_ERC20_ENCODING.assetData,
);
});
it('should decode ERC20 asset data', async () => {
expect(await libAssetData.decodeERC20AssetData.callAsync(KNOWN_ERC20_ENCODING.assetData)).to.deep.equal([
AssetProxyId.ERC20,
KNOWN_ERC20_ENCODING.address,
]);
});
it('should encode ERC721 asset data', async () => {
expect(
await libAssetData.encodeERC721AssetData.callAsync(
KNOWN_ERC721_ENCODING.address,
KNOWN_ERC721_ENCODING.tokenId,
),
).to.equal(KNOWN_ERC721_ENCODING.assetData);
});
it('should decode ERC721 asset data', async () => {
expect(await libAssetData.decodeERC721AssetData.callAsync(KNOWN_ERC721_ENCODING.assetData)).to.deep.equal([
AssetProxyId.ERC721,
KNOWN_ERC721_ENCODING.address,
KNOWN_ERC721_ENCODING.tokenId,
]);
});
it('should encode ERC1155 asset data', async () => {
expect(
await libAssetData.encodeERC1155AssetData.callAsync(
KNOWN_ERC1155_ENCODING.tokenAddress,
KNOWN_ERC1155_ENCODING.tokenIds,
KNOWN_ERC1155_ENCODING.tokenValues,
KNOWN_ERC1155_ENCODING.callbackData,
),
).to.equal(KNOWN_ERC1155_ENCODING.assetData);
});
it('should decode ERC1155 asset data', async () => {
expect(await libAssetData.decodeERC1155AssetData.callAsync(KNOWN_ERC1155_ENCODING.assetData)).to.deep.equal(
[
AssetProxyId.ERC1155,
KNOWN_ERC1155_ENCODING.tokenAddress,
KNOWN_ERC1155_ENCODING.tokenIds,
KNOWN_ERC1155_ENCODING.tokenValues,
KNOWN_ERC1155_ENCODING.callbackData,
],
);
});
it('should encode multiasset data', async () => {
expect(
await libAssetData.encodeMultiAssetData.callAsync(
KNOWN_MULTI_ASSET_ENCODING.amounts,
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
),
).to.equal(KNOWN_MULTI_ASSET_ENCODING.assetData);
});
it('should decode multiasset data', async () => {
expect(
await libAssetData.decodeMultiAssetData.callAsync(KNOWN_MULTI_ASSET_ENCODING.assetData),
).to.deep.equal([
AssetProxyId.MultiAsset,
KNOWN_MULTI_ASSET_ENCODING.amounts,
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
]);
});
});
describe('getBalance', () => {
it('should query ERC20 balance by asset data', async () => {
const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal(
erc20TokenTotalSupply,
);
});
it('should return 0 if ERC20 token does not exist', async () => {
const assetData = assetDataUtils.encodeERC20AssetData(constants.NULL_ADDRESS);
const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData);
expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should query ERC721 balance by asset data', async () => {
const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId);
expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal(1);
});
it('should return 0 if ERC721 token does not exist', async () => {
const assetData = assetDataUtils.encodeERC721AssetData(constants.NULL_ADDRESS, firstERC721TokenId);
const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData);
expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should query ERC1155 balances by asset data', async () => {
const assetData = assetDataUtils.encodeERC1155AssetData(
erc1155Token.address,
[erc1155TokenId],
[new BigNumber(1)],
constants.NULL_BYTES,
);
expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal(1);
});
it('should return 0 if ERC1155 token does not exist', async () => {
const assetData = assetDataUtils.encodeERC1155AssetData(
constants.NULL_ADDRESS,
[erc1155TokenId],
[new BigNumber(1)],
constants.NULL_BYTES,
);
const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData);
expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should query multi-asset batch balance by asset data', async () => {
const assetData = assetDataUtils.encodeMultiAssetData(
[new BigNumber(1), new BigNumber(1)],
[
assetDataUtils.encodeERC20AssetData(erc20Token.address),
assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId),
],
);
expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal(
Math.min(erc20TokenTotalSupply.toNumber(), numberOfERC721Tokens),
);
});
it('should return a balance of 0 if the assetData does not correspond to an AssetProxy contract', async () => {
const fakeAssetData = '0x01020304';
const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, fakeAssetData);
expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should return a balance of MAX_UINT256 if the the StaticCallProxy assetData contains data for a successful staticcall', async () => {
const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(1));
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData);
expect(balance).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
it('should return a balance of 0 if the the StaticCallProxy assetData contains data for an unsuccessful staticcall', async () => {
const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0));
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
expectedResultHash,
);
const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData);
expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT);
});
});
describe('getAssetProxyAllowance', () => {
it('should query ERC20 allowances by asset data', async () => {
const allowance = new BigNumber(1);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: tokenOwnerAddress,
});
const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
expect(
await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData),
).to.bignumber.equal(allowance);
});
it('should query ERC721 approval by asset data', async () => {
await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, {
from: tokenOwnerAddress,
});
const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId);
expect(
await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData),
).to.bignumber.equal(1);
});
it('should query ERC721 approvalForAll by assetData', async () => {
await erc721Token.setApprovalForAll.awaitTransactionSuccessAsync(erc721Proxy.address, true, {
from: tokenOwnerAddress,
});
const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId);
expect(
await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData),
).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
it('should query ERC1155 allowances by asset data', async () => {
await erc1155Token.setApprovalForAll.awaitTransactionSuccessAsync(erc1155Proxy.address, true, {
from: tokenOwnerAddress,
});
const assetData = assetDataUtils.encodeERC1155AssetData(
erc1155Token.address,
[erc1155TokenId],
[new BigNumber(1)],
constants.NULL_BYTES,
);
expect(
await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData),
).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
it('should query multi-asset allowances by asset data', async () => {
const allowance = new BigNumber(1);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: tokenOwnerAddress,
});
await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, {
from: tokenOwnerAddress,
});
const assetData = assetDataUtils.encodeMultiAssetData(
[new BigNumber(1), new BigNumber(1)],
[
assetDataUtils.encodeERC20AssetData(erc20Token.address),
assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId),
],
);
expect(
await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData),
).to.bignumber.equal(1);
return;
});
it('should return an allowance of 0 if the assetData does not correspond to an AssetProxy contract', async () => {
const fakeAssetData = '0x01020304';
const allowance = await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, fakeAssetData);
expect(allowance).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should return an allowance of MAX_UINT256 for any staticCallAssetData', async () => {
const staticCallData = AssetProxyId.StaticCall;
const assetData = assetDataUtils.encodeStaticCallAssetData(
staticCallTarget.address,
staticCallData,
constants.KECCAK256_NULL,
);
const allowance = await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData);
expect(allowance).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
});
describe('getBatchBalances', () => {
it('should query balances for a batch of asset data strings', async () => {
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId);
expect(
await libAssetData.getBatchBalances.callAsync(tokenOwnerAddress, [erc20AssetData, erc721AssetData]),
).to.deep.equal([new BigNumber(erc20TokenTotalSupply), new BigNumber(1)]);
});
});
describe('getERC721TokenOwner', async () => {
it('should return the null address when tokenId is not owned', async () => {
const nonexistentTokenId = new BigNumber(1234567890);
expect(
await libAssetData.getERC721TokenOwner.callAsync(erc721Token.address, nonexistentTokenId),
).to.be.equal(constants.NULL_ADDRESS);
});
it('should return the owner address when tokenId is owned', async () => {
expect(
await libAssetData.getERC721TokenOwner.callAsync(erc721Token.address, firstERC721TokenId),
).to.be.equal(tokenOwnerAddress);
});
});
describe('getBalanceAndAllowance', () => {
it('should query balance and allowance together, from asset data', async () => {
const allowance = new BigNumber(1);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: tokenOwnerAddress,
});
const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
expect(
await libAssetData.getBalanceAndAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData),
).to.deep.equal([new BigNumber(erc20TokenTotalSupply), allowance]);
});
});
describe('getBatchBalancesAndAllowances', () => {
it('should query balances and allowances together, from an asset data array', async () => {
const allowance = new BigNumber(1);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: tokenOwnerAddress,
});
const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
expect(
await libAssetData.getBatchBalancesAndAssetProxyAllowances.callAsync(tokenOwnerAddress, [assetData]),
).to.deep.equal([[new BigNumber(erc20TokenTotalSupply)], [allowance]]);
});
});
describe('getBatchAssetProxyAllowances', () => {
it('should query allowances for a batch of asset data strings', async () => {
const allowance = new BigNumber(1);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: tokenOwnerAddress,
});
await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, {
from: tokenOwnerAddress,
});
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId);
expect(
await libAssetData.getBatchAssetProxyAllowances.callAsync(tokenOwnerAddress, [
erc20AssetData,
erc721AssetData,
]),
).to.deep.equal([new BigNumber(1), new BigNumber(1)]);
});
});
});
// tslint:disable:max-file-line-count

View File

@@ -0,0 +1,139 @@
import { IExchangeContract } from '@0x/contracts-exchange';
import { chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import { artifacts, LibTransactionDecoderContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const order = {
makerAddress: '0xe36ea790bc9d7ab70c55260c66d52b1eca985f84',
takerAddress: '0x0000000000000000000000000000000000000000',
feeRecipientAddress: '0x78dc5d2d739606d31509c31d654056a45185ecb6',
senderAddress: '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb',
makerAssetAmount: new BigNumber('100000000000000000000'),
takerAssetAmount: new BigNumber('200000000000000000000'),
makerFee: new BigNumber('1000000000000000000'),
takerFee: new BigNumber('1000000000000000000'),
expirationTimeSeconds: new BigNumber('1552396423'),
salt: new BigNumber('66097384406870180066678463045003379626790660770396923976862707230261946348951'),
makerAssetData: '0xf47261b000000000000000000000000034d402f14d58e001d8efbe6585051bf9706aa064',
takerAssetData: '0xf47261b000000000000000000000000025b8fe1de9daf8ba351890744ff28cf7dfa8f5e3',
};
const takerAssetFillAmount = new BigNumber('100000000000000000000');
const signature =
'0x1ce8e3c600d933423172b5021158a6be2e818613ff8e762d70ef490c752fd98a626a215f09f169668990414de75a53da221c294a3002f796d004827258b641876e03';
describe('LibTransactionDecoder', () => {
let libTxDecoder: LibTransactionDecoderContract;
const exchangeInterface = new IExchangeContract(constants.NULL_ADDRESS, provider, txDefaults);
before(async () => {
await blockchainLifecycle.startAsync();
libTxDecoder = await LibTransactionDecoderContract.deployFrom0xArtifactAsync(
artifacts.LibTransactionDecoder,
provider,
txDefaults,
);
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
it('should decode an Exchange.batchCancelOrders() transaction', async () => {
const input = exchangeInterface.batchCancelOrders.getABIEncodedTransactionData([order, order]);
expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([
'batchCancelOrders',
[order, order],
[],
[],
]);
});
for (const func of ['batchFillOrders', 'batchFillOrdersNoThrow', 'batchFillOrKillOrders']) {
const input = (exchangeInterface as any)[func].getABIEncodedTransactionData(
[order, order],
[takerAssetFillAmount, takerAssetFillAmount],
[signature, signature],
);
it(`should decode an Exchange.${func}() transaction`, async () => {
expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([
func,
[order, order],
[takerAssetFillAmount, takerAssetFillAmount],
[signature, signature],
]);
});
}
it('should decode an Exchange.cancelOrder() transaction', async () => {
const input = exchangeInterface.cancelOrder.getABIEncodedTransactionData(order);
expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([
'cancelOrder',
[order],
[],
[],
]);
});
for (const func of ['fillOrder', 'fillOrderNoThrow', 'fillOrKillOrder']) {
const input = (exchangeInterface as any)[func].getABIEncodedTransactionData(
order,
takerAssetFillAmount,
signature,
);
it(`should decode an Exchange.${func}() transaction`, async () => {
expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([
func,
[order],
[takerAssetFillAmount],
[signature],
]);
});
}
for (const func of ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow']) {
const input = (exchangeInterface as any)[func].getABIEncodedTransactionData(
[order, order],
takerAssetFillAmount,
[signature, signature],
);
it(`should decode an Exchange.${func}() transaction`, async () => {
expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([
func,
[order, order],
[takerAssetFillAmount],
[signature, signature],
]);
});
}
it('should decode an Exchange.matchOrders() transaction', async () => {
const complementaryOrder = {
...order,
makerAddress: order.takerAddress,
takerAddress: order.makerAddress,
makerAssetData: order.takerAssetData,
takerAssetData: order.makerAssetData,
makerAssetAmount: order.takerAssetAmount,
takerAssetAmount: order.makerAssetAmount,
makerFee: order.takerFee,
takerFee: order.makerFee,
};
const input = exchangeInterface.matchOrders.getABIEncodedTransactionData(
order,
complementaryOrder,
signature,
signature,
);
expect(await libTxDecoder.decodeZeroExTransactionData.callAsync(input)).to.deep.equal([
'matchOrders',
[order, complementaryOrder],
[order.takerAssetAmount, complementaryOrder.takerAssetAmount],
[signature, signature],
]);
});
});

View File

@@ -0,0 +1,442 @@
import {
artifacts as proxyArtifacts,
ERC20ProxyContract,
ERC20Wrapper,
ERC721ProxyContract,
ERC721Wrapper,
MultiAssetProxyContract,
} from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
import { artifacts as exchangeArtifacts, ExchangeContract, ExchangeWrapper } from '@0x/contracts-exchange';
import {
chaiSetup,
constants,
OrderFactory,
OrderStatus,
provider,
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
import { SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import { artifacts, DevUtilsContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('OrderValidationUtils', () => {
let makerAddress: string;
let takerAddress: string;
let owner: string;
let erc20AssetData: string;
let erc20AssetData2: string;
let erc721AssetData: string;
let zrxAssetData: string;
let erc20Token: DummyERC20TokenContract;
let erc20Token2: DummyERC20TokenContract;
let zrxToken: DummyERC20TokenContract;
let erc721Token: DummyERC721TokenContract;
let exchange: ExchangeContract;
let devUtils: DevUtilsContract;
let erc20Proxy: ERC20ProxyContract;
let erc721Proxy: ERC721ProxyContract;
let multiAssetProxy: MultiAssetProxyContract;
let signedOrder: SignedOrder;
let orderFactory: OrderFactory;
const tokenId = new BigNumber(123456789);
before(async () => {
await blockchainLifecycle.startAsync();
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync();
const usedAddresses = ([owner, makerAddress, takerAddress] = accounts.slice(0, 3));
const erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
const erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner);
const numDummyErc20ToDeploy = 3;
[erc20Token, zrxToken, erc20Token2] = await erc20Wrapper.deployDummyTokensAsync(
numDummyErc20ToDeploy,
constants.DUMMY_TOKEN_DECIMALS,
);
erc20Proxy = await erc20Wrapper.deployProxyAsync();
[erc721Token] = await erc721Wrapper.deployDummyTokensAsync();
erc721Proxy = await erc721Wrapper.deployProxyAsync();
zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
exchangeArtifacts.Exchange,
provider,
txDefaults,
zrxAssetData,
);
multiAssetProxy = await MultiAssetProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.MultiAssetProxy,
provider,
txDefaults,
);
const exchangeWrapper = new ExchangeWrapper(exchange, provider);
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(multiAssetProxy.address, owner);
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(exchange.address, { from: owner });
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(exchange.address, { from: owner });
devUtils = await DevUtilsContract.deployFrom0xArtifactAsync(
artifacts.DevUtils,
provider,
txDefaults,
exchange.address,
zrxAssetData,
);
erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20Token2.address);
erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, tokenId);
const defaultOrderParams = {
...constants.STATIC_ORDER_PARAMS,
exchangeAddress: exchange.address,
makerAddress,
feeRecipientAddress: constants.NULL_ADDRESS,
makerAssetData: erc20AssetData,
takerAssetData: erc20AssetData2,
};
const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
describe('getTransferableAssetAmount', () => {
it('should return the balance when balance < allowance', async () => {
const balance = new BigNumber(123);
const allowance = new BigNumber(456);
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, balance);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: makerAddress,
});
const transferableAmount = await devUtils.getTransferableAssetAmount.callAsync(
makerAddress,
erc20AssetData,
);
expect(transferableAmount).to.bignumber.equal(balance);
});
it('should return the allowance when allowance < balance', async () => {
const balance = new BigNumber(456);
const allowance = new BigNumber(123);
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, balance);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: makerAddress,
});
const transferableAmount = await devUtils.getTransferableAssetAmount.callAsync(
makerAddress,
erc20AssetData,
);
expect(transferableAmount).to.bignumber.equal(allowance);
});
it('should return the correct transferable amount for multiAssetData', async () => {
const multiAssetData = assetDataUtils.encodeMultiAssetData(
[new BigNumber(1), new BigNumber(1)],
[erc20AssetData, erc20AssetData2],
);
const transferableAmount1 = new BigNumber(10);
const transferableAmount2 = new BigNumber(5);
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, transferableAmount1);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, transferableAmount1, {
from: makerAddress,
});
await erc20Token2.setBalance.awaitTransactionSuccessAsync(makerAddress, transferableAmount2);
await erc20Token2.approve.awaitTransactionSuccessAsync(erc20Proxy.address, transferableAmount2, {
from: makerAddress,
});
const transferableAmount = await devUtils.getTransferableAssetAmount.callAsync(
makerAddress,
multiAssetData,
);
expect(transferableAmount).to.bignumber.equal(transferableAmount2);
});
});
describe('getOrderRelevantState', () => {
beforeEach(async () => {
signedOrder = await orderFactory.newSignedOrderAsync();
});
it('should return the correct orderInfo when the order is valid', async () => {
const [orderInfo] = await devUtils.getOrderRelevantState.callAsync(signedOrder, signedOrder.signature);
expect(orderInfo.orderHash).to.equal(orderHashUtils.getOrderHashHex(signedOrder));
expect(orderInfo.orderStatus).to.equal(OrderStatus.Fillable);
expect(orderInfo.orderTakerAssetFilledAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should return isValidSignature=true when the signature is valid', async () => {
const [, , isValidSignature] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(isValidSignature).to.equal(true);
});
it('should return isValidSignature=false when the signature is invalid', async () => {
const invalidSignature = '0x01';
const [, , isValidSignature] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
invalidSignature,
);
expect(isValidSignature).to.equal(false);
});
it('should return a fillableTakerAssetAmount of 0 when balances or allowances are insufficient', async () => {
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should return a fillableTakerAssetAmount of 0 when fee balances/allowances are insufficient', async () => {
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should return a fillableTakerAssetAmount of 0 when balances/allowances of one asset within a multiAssetData are insufficient', async () => {
const multiAssetData = assetDataUtils.encodeMultiAssetData(
[new BigNumber(1), new BigNumber(1)],
[erc20AssetData, erc20AssetData2],
);
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: multiAssetData });
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should return the correct fillableTakerAssetAmount when fee balances/allowances are partially sufficient', async () => {
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
const divisor = 4;
await zrxToken.setBalance.awaitTransactionSuccessAsync(
makerAddress,
signedOrder.makerFee.dividedToIntegerBy(divisor),
);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, {
from: makerAddress,
});
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(
signedOrder.takerAssetAmount.dividedToIntegerBy(divisor),
);
});
it('should return the correct fillableTakerAssetAmount when non-fee balances/allowances are partially sufficient', async () => {
const divisor = 4;
await erc20Token.setBalance.awaitTransactionSuccessAsync(
makerAddress,
signedOrder.makerAssetAmount.dividedToIntegerBy(divisor),
);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, {
from: makerAddress,
});
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(
signedOrder.takerAssetAmount.dividedToIntegerBy(divisor),
);
});
it('should return the correct fillableTakerAssetAmount when balances/allowances of one asset within a multiAssetData are partially sufficient', async () => {
const multiAssetData = assetDataUtils.encodeMultiAssetData(
[new BigNumber(1), new BigNumber(1)],
[erc20AssetData, erc20AssetData2],
);
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: multiAssetData });
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, {
from: makerAddress,
});
const divisor = 4;
await erc20Token2.setBalance.awaitTransactionSuccessAsync(
makerAddress,
signedOrder.makerAssetAmount.dividedToIntegerBy(divisor),
);
await erc20Token2.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
signedOrder.makerAssetAmount.dividedToIntegerBy(divisor),
{
from: makerAddress,
},
);
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(
signedOrder.takerAssetAmount.dividedToIntegerBy(divisor),
);
});
it('should return a fillableTakerAssetAmount of 0 when non-fee balances/allowances are insufficient', async () => {
await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, {
from: makerAddress,
});
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should return a fillableTakerAssetAmount equal to the takerAssetAmount when the order is unfilled and balances/allowances are sufficient', async () => {
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, {
from: makerAddress,
});
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(signedOrder.takerAssetAmount);
});
it('should return the correct fillableTakerAssetAmount when balances/allowances are partially sufficient and makerAsset=makerFeeAsset', async () => {
signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetData: zrxAssetData,
makerAssetAmount: new BigNumber(10),
takerAssetAmount: new BigNumber(20),
makerFee: new BigNumber(40),
});
const transferableMakerAssetAmount = new BigNumber(10);
await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, transferableMakerAssetAmount);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, transferableMakerAssetAmount, {
from: makerAddress,
});
const expectedFillableTakerAssetAmount = transferableMakerAssetAmount
.times(signedOrder.takerAssetAmount)
.dividedToIntegerBy(signedOrder.makerAssetAmount.plus(signedOrder.makerFee));
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(expectedFillableTakerAssetAmount);
});
it('should return the correct fillabeTakerassetAmount when makerAsset balances/allowances are sufficient and there are no maker fees', async () => {
signedOrder = await orderFactory.newSignedOrderAsync({ makerFee: constants.ZERO_AMOUNT });
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(signedOrder.takerAssetAmount);
});
it('should return a fillableTakerAssetAmount when the remaining takerAssetAmount is less than the transferable amount', async () => {
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, {
from: makerAddress,
});
await erc20Token2.setBalance.awaitTransactionSuccessAsync(takerAddress, signedOrder.takerAssetAmount);
await erc20Token2.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.takerAssetAmount, {
from: takerAddress,
});
await zrxToken.setBalance.awaitTransactionSuccessAsync(takerAddress, signedOrder.takerFee);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.takerFee, {
from: takerAddress,
});
const takerAssetFillAmount = signedOrder.takerAssetAmount.dividedToIntegerBy(4);
await exchange.fillOrder.awaitTransactionSuccessAsync(
signedOrder,
takerAssetFillAmount,
signedOrder.signature,
{ from: takerAddress },
);
const [, fillableTakerAssetAmount] = await devUtils.getOrderRelevantState.callAsync(
signedOrder,
signedOrder.signature,
);
expect(fillableTakerAssetAmount).to.bignumber.equal(
signedOrder.takerAssetAmount.minus(takerAssetFillAmount),
);
});
});
describe('getOrderRelevantStates', async () => {
it('should return the correct information for multiple orders', async () => {
await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount);
await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, {
from: makerAddress,
});
await zrxToken.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee);
await zrxToken.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, {
from: makerAddress,
});
const signedOrder2 = await orderFactory.newSignedOrderAsync({ makerAssetData: erc721AssetData });
const invalidSignature = '0x01';
await exchange.cancelOrder.awaitTransactionSuccessAsync(signedOrder2, { from: makerAddress });
const [
ordersInfo,
fillableTakerAssetAmounts,
isValidSignature,
] = await devUtils.getOrderRelevantStates.callAsync(
[signedOrder, signedOrder2],
[signedOrder.signature, invalidSignature],
);
expect(ordersInfo[0].orderHash).to.equal(orderHashUtils.getOrderHashHex(signedOrder));
expect(ordersInfo[1].orderHash).to.equal(orderHashUtils.getOrderHashHex(signedOrder2));
expect(ordersInfo[0].orderStatus).to.equal(OrderStatus.Fillable);
expect(ordersInfo[1].orderStatus).to.equal(OrderStatus.Cancelled);
expect(ordersInfo[0].orderTakerAssetFilledAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
expect(ordersInfo[1].orderTakerAssetFilledAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
expect(fillableTakerAssetAmounts[0]).to.bignumber.equal(signedOrder.takerAssetAmount);
expect(fillableTakerAssetAmounts[1]).to.bignumber.equal(constants.ZERO_AMOUNT);
expect(isValidSignature[0]).to.equal(true);
expect(isValidSignature[1]).to.equal(false);
});
});
});
// tslint:disable:max-file-line-count

View File

@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig",
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": [
"generated-artifacts/DevUtils.json",
"generated-artifacts/LibAssetData.json",
"generated-artifacts/LibTransactionDecoder.json",
"generated-artifacts/EthBalanceChecker.json"
],
"exclude": ["./deploy/solc/solc_bin"]
}

View File

@@ -0,0 +1,6 @@
{
"extends": ["@0x/tslint-config"],
"rules": {
"custom-no-magic-numbers": false
}
}

View File

@@ -1,4 +1,68 @@
[
{
"timestamp": 1563006338,
"version": "1.1.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1558712885,
"version": "1.1.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557961111,
"version": "1.1.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.1.4",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1557799313
},
{
"timestamp": 1557507213,
"version": "1.1.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.1.1",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1554997931
},
{
"version": "1.1.0",
"changes": [
{
"note": "Run Web3ProviderEngine without excess block polling",
"pr": 1695
}
],
"timestamp": 1553183790
},
{
"timestamp": 1553091633,
"version": "1.0.1",

View File

@@ -5,6 +5,34 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.1.7 - _July 13, 2019_
* Dependencies updated
## v1.1.6 - _May 24, 2019_
* Dependencies updated
## v1.1.5 - _May 15, 2019_
* Dependencies updated
## v1.1.4 - _May 14, 2019_
* Dependencies updated
## v1.1.2 - _May 10, 2019_
* Dependencies updated
## v1.1.1 - _April 11, 2019_
* Dependencies updated
## v1.1.0 - _March 21, 2019_
* Run Web3ProviderEngine without excess block polling (#1695)
## v1.0.1 - _March 20, 2019_
* Dependencies updated

View File

@@ -1,7 +1,7 @@
{
"artifactsDir": "generated-artifacts",
"contractsDir": "contracts",
"useDockerisedSolc": true,
"useDockerisedSolc": false,
"compilerSettings": {
"evmVersion": "constantinople",
"optimizer": { "enabled": true, "runs": 1000000 },
@@ -9,6 +9,7 @@
"*": {
"*": [
"abi",
"devdoc",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",

View File

@@ -63,6 +63,32 @@ contract ERC1155Mintable is
}
}
/// @dev creates a new token
/// @param type_ of token
/// @param uri URI of token
function createWithType(
uint256 type_,
string calldata uri
)
external
{
// This will allow restricted access to creators.
creators[type_] = msg.sender;
// emit a Transfer event with Create semantic to help with discovery.
emit TransferSingle(
msg.sender,
address(0x0),
address(0x0),
type_,
0
);
if (bytes(uri).length > 0) {
emit URI(uri, type_);
}
}
/// @dev mints fungible tokens
/// @param id token type
/// @param to beneficiaries of minted tokens

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc1155",
"version": "1.0.1",
"version": "1.1.7",
"engines": {
"node": ">=6.12"
},
@@ -24,6 +24,7 @@
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html",
@@ -46,12 +47,11 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
"devDependencies": {
"@0x/abi-gen": "^2.0.7",
"@0x/contracts-gen": "^1.0.6",
"@0x/contracts-test-utils": "^3.1.0",
"@0x/dev-utils": "^2.1.4",
"@0x/sol-compiler": "^3.1.4",
"@0x/tslint-config": "^3.0.0",
"@0x/abi-gen": "^2.1.0",
"@0x/contracts-gen": "^1.0.10",
"@0x/dev-utils": "^2.2.4",
"@0x/sol-compiler": "^3.1.9",
"@0x/tslint-config": "^3.0.1",
"@types/lodash": "4.14.104",
"@types/node": "*",
"chai": "^4.0.1",
@@ -67,13 +67,14 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.0.3",
"@0x/contracts-utils": "^3.0.0",
"@0x/types": "^2.2.0",
"@0x/typescript-typings": "^4.2.0",
"@0x/utils": "^4.2.3",
"@0x/web3-wrapper": "^6.0.3",
"ethereum-types": "^2.1.1",
"@0x/base-contract": "^5.1.1",
"@0x/contracts-test-utils": "^3.1.8",
"@0x/contracts-utils": "^3.1.7",
"@0x/types": "^2.4.0",
"@0x/typescript-typings": "^4.2.3",
"@0x/utils": "^4.4.0",
"@0x/web3-wrapper": "^6.0.7",
"ethereum-types": "^2.1.3",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -1,8 +1,10 @@
import { env, EnvVars } from '@0x/dev-utils';
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
import { providerUtils } from '@0x/utils';
before('start web3 provider', () => {
provider.start();
providerUtils.startProviderEngine(provider);
});
after('generate coverage report', async () => {
if (env.parseBoolean(EnvVars.SolidityCoverage)) {

View File

@@ -36,8 +36,8 @@ export class Erc1155Wrapper {
callbackData?: string,
delegatedSpender?: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const spender = _.isUndefined(delegatedSpender) ? from : delegatedSpender;
const callbackDataHex = _.isUndefined(callbackData) ? '0x' : callbackData;
const spender = delegatedSpender === undefined ? from : delegatedSpender;
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
await this._erc1155Contract.safeTransferFrom.sendTransactionAsync(from, to, token, value, callbackDataHex, {
from: spender,
@@ -53,8 +53,8 @@ export class Erc1155Wrapper {
callbackData?: string,
delegatedSpender?: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const spender = _.isUndefined(delegatedSpender) ? from : delegatedSpender;
const callbackDataHex = _.isUndefined(callbackData) ? '0x' : callbackData;
const spender = delegatedSpender === undefined ? from : delegatedSpender;
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
await this._erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
from,

View File

@@ -1,4 +1,69 @@
[
{
"timestamp": 1563006338,
"version": "2.2.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1558712885,
"version": "2.2.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557961111,
"version": "2.2.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.2.3",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1557799313
},
{
"timestamp": 1557507213,
"version": "2.2.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.2.0",
"changes": [
{
"note": "Added UntransferrableDummyERC20Token",
"pr": 1714
}
],
"timestamp": 1554997931
},
{
"version": "2.1.0",
"changes": [
{
"note": "Run Web3ProviderEngine without excess block polling",
"pr": 1695
}
],
"timestamp": 1553183790
},
{
"version": "2.0.0",
"changes": [

View File

@@ -5,6 +5,34 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.2.6 - _July 13, 2019_
* Dependencies updated
## v2.2.5 - _May 24, 2019_
* Dependencies updated
## v2.2.4 - _May 15, 2019_
* Dependencies updated
## v2.2.3 - _May 14, 2019_
* Dependencies updated
## v2.2.1 - _May 10, 2019_
* Dependencies updated
## v2.2.0 - _April 11, 2019_
* Added UntransferrableDummyERC20Token (#1714)
## v2.1.0 - _March 21, 2019_
* Run Web3ProviderEngine without excess block polling (#1695)
## v2.0.0 - _March 20, 2019_
* Upgrade contracts to Solidity 0.5.5 (#1682)

View File

@@ -1,7 +1,7 @@
{
"artifactsDir": "./generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": true,
"useDockerisedSolc": false,
"isOfflineMode": false,
"compilerSettings": {
"evmVersion": "constantinople",
@@ -14,10 +14,12 @@
"*": {
"*": [
"abi",
"devdoc",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
"evm.deployedBytecode.sourceMap"
"evm.deployedBytecode.sourceMap",
"devdoc"
]
}
}
@@ -32,6 +34,7 @@
"src/interfaces/IEtherToken.sol",
"test/DummyERC20Token.sol",
"test/DummyMultipleReturnERC20Token.sol",
"test/DummyNoReturnERC20Token.sol"
"test/DummyNoReturnERC20Token.sol",
"test/UntransferrableDummyERC20Token.sol"
]
}

View File

@@ -0,0 +1,61 @@
/*
Copyright 2018 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.5;
import "./DummyERC20Token.sol";
// solhint-disable no-empty-blocks
contract UntransferrableDummyERC20Token is
DummyERC20Token
{
constructor (
string memory _name,
string memory _symbol,
uint256 _decimals,
uint256 _totalSupply
)
public
DummyERC20Token(
_name,
_symbol,
_decimals,
_totalSupply
)
{}
/// @dev send `value` token to `to` from `from` on the condition it is approved by `from`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
function transferFrom(
address _from,
address _to,
uint256 _value
)
external
returns (bool)
{
require(
false,
"TRANSFER_DISABLED"
);
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc20",
"version": "2.0.0",
"version": "2.2.6",
"engines": {
"node": ">=6.12"
},
@@ -24,6 +24,7 @@
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html",
@@ -46,12 +47,12 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
"devDependencies": {
"@0x/abi-gen": "^2.0.7",
"@0x/contracts-gen": "^1.0.6",
"@0x/contracts-test-utils": "^3.1.0",
"@0x/dev-utils": "^2.1.4",
"@0x/sol-compiler": "^3.1.4",
"@0x/tslint-config": "^3.0.0",
"@0x/abi-gen": "^2.1.0",
"@0x/contracts-gen": "^1.0.10",
"@0x/contracts-test-utils": "^3.1.8",
"@0x/dev-utils": "^2.2.4",
"@0x/sol-compiler": "^3.1.9",
"@0x/tslint-config": "^3.0.1",
"@types/lodash": "4.14.104",
"@types/node": "*",
"chai": "^4.0.1",
@@ -67,14 +68,13 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.0.3",
"@0x/contracts-exchange-libs": "^2.0.0",
"@0x/contracts-utils": "^3.0.0",
"@0x/types": "^2.2.0",
"@0x/typescript-typings": "^4.2.0",
"@0x/utils": "^4.2.3",
"@0x/web3-wrapper": "^6.0.3",
"ethereum-types": "^2.1.1",
"@0x/base-contract": "^5.1.1",
"@0x/contracts-utils": "^3.1.7",
"@0x/types": "^2.4.0",
"@0x/typescript-typings": "^4.2.3",
"@0x/utils": "^4.4.0",
"@0x/web3-wrapper": "^6.0.7",
"ethereum-types": "^2.1.3",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -1,8 +1,10 @@
import { env, EnvVars } from '@0x/dev-utils';
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
import { providerUtils } from '@0x/utils';
before('start web3 provider', () => {
provider.start();
providerUtils.startProviderEngine(provider);
});
after('generate coverage report', async () => {
if (env.parseBoolean(EnvVars.SolidityCoverage)) {

View File

@@ -1,4 +1,68 @@
[
{
"timestamp": 1563006338,
"version": "2.1.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1558712885,
"version": "2.1.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557961111,
"version": "2.1.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.1.4",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1557799313
},
{
"timestamp": 1557507213,
"version": "2.1.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.1.1",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1554997931
},
{
"version": "2.1.0",
"changes": [
{
"note": "Run Web3ProviderEngine without excess block polling",
"pr": 1695
}
],
"timestamp": 1553183790
},
{
"version": "2.0.0",
"changes": [

View File

@@ -5,6 +5,34 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.1.7 - _July 13, 2019_
* Dependencies updated
## v2.1.6 - _May 24, 2019_
* Dependencies updated
## v2.1.5 - _May 15, 2019_
* Dependencies updated
## v2.1.4 - _May 14, 2019_
* Dependencies updated
## v2.1.2 - _May 10, 2019_
* Dependencies updated
## v2.1.1 - _April 11, 2019_
* Dependencies updated
## v2.1.0 - _March 21, 2019_
* Run Web3ProviderEngine without excess block polling (#1695)
## v2.0.0 - _March 20, 2019_
* Upgrade contracts to Solidity 0.5.5 (#1682)

View File

@@ -1,7 +1,7 @@
{
"artifactsDir": "./generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": true,
"useDockerisedSolc": false,
"isOfflineMode": false,
"compilerSettings": {
"evmVersion": "constantinople",
@@ -14,6 +14,7 @@
"*": {
"*": [
"abi",
"devdoc",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc721",
"version": "2.0.0",
"version": "2.1.7",
"engines": {
"node": ">=6.12"
},
@@ -24,6 +24,7 @@
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html",
@@ -46,12 +47,12 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
"devDependencies": {
"@0x/abi-gen": "^2.0.7",
"@0x/contracts-gen": "^1.0.6",
"@0x/contracts-test-utils": "^3.1.0",
"@0x/dev-utils": "^2.1.4",
"@0x/sol-compiler": "^3.1.4",
"@0x/tslint-config": "^3.0.0",
"@0x/abi-gen": "^2.1.0",
"@0x/contracts-gen": "^1.0.10",
"@0x/contracts-test-utils": "^3.1.8",
"@0x/dev-utils": "^2.2.4",
"@0x/sol-compiler": "^3.1.9",
"@0x/tslint-config": "^3.0.1",
"@types/lodash": "4.14.104",
"@types/node": "*",
"chai": "^4.0.1",
@@ -67,13 +68,13 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.0.3",
"@0x/contracts-utils": "^3.0.0",
"@0x/types": "^2.2.0",
"@0x/typescript-typings": "^4.2.0",
"@0x/utils": "^4.2.3",
"@0x/web3-wrapper": "^6.0.3",
"ethereum-types": "^2.1.1",
"@0x/base-contract": "^5.1.1",
"@0x/contracts-utils": "^3.1.7",
"@0x/types": "^2.4.0",
"@0x/typescript-typings": "^4.2.3",
"@0x/utils": "^4.4.0",
"@0x/web3-wrapper": "^6.0.7",
"ethereum-types": "^2.1.3",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -1,8 +1,10 @@
import { env, EnvVars } from '@0x/dev-utils';
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
import { providerUtils } from '@0x/utils';
before('start web3 provider', () => {
provider.start();
providerUtils.startProviderEngine(provider);
});
after('generate coverage report', async () => {
if (env.parseBoolean(EnvVars.SolidityCoverage)) {

View File

@@ -1,4 +1,69 @@
[
{
"timestamp": 1563006338,
"version": "3.0.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1558712885,
"version": "3.0.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557961111,
"version": "3.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1557799313,
"version": "3.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "3.0.0",
"changes": [
{
"note": "Update contracts to solidity ^0.5.5 and unpin dependencies",
"pr": 1796
}
],
"timestamp": 1557507213
},
{
"version": "2.1.1",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1554997931
},
{
"version": "2.1.0",
"changes": [
{
"note": "Run Web3ProviderEngine without excess block polling",
"pr": 1695
}
],
"timestamp": 1553183790
},
{
"version": "2.0.0",
"changes": [

View File

@@ -5,6 +5,34 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.0.4 - _July 13, 2019_
* Dependencies updated
## v3.0.3 - _May 24, 2019_
* Dependencies updated
## v3.0.2 - _May 15, 2019_
* Dependencies updated
## v3.0.1 - _May 14, 2019_
* Dependencies updated
## v3.0.0 - _May 10, 2019_
* Update contracts to solidity ^0.5.5 and unpin dependencies (#1796)
## v2.1.1 - _April 11, 2019_
* Dependencies updated
## v2.1.0 - _March 21, 2019_
* Run Web3ProviderEngine without excess block polling (#1695)
## v2.0.0 - _March 20, 2019_
* Do not reexport external dependencies (#1682)

View File

@@ -1,7 +1,7 @@
{
"artifactsDir": "./generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": true,
"useDockerisedSolc": false,
"isOfflineMode": false,
"compilerSettings": {
"evmVersion": "constantinople",
@@ -14,6 +14,7 @@
"*": {
"*": [
"abi",
"devdoc",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",

View File

@@ -16,7 +16,7 @@
*/
pragma solidity 0.4.24;
pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "./MixinWeth.sol";
@@ -40,6 +40,7 @@ contract Forwarder is
bytes memory _wethAssetData
)
public
Ownable()
LibConstants(
_exchange,
_zrxAssetData,

View File

@@ -16,7 +16,7 @@
*/
pragma solidity ^0.4.24;
pragma solidity ^0.5.5;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-utils/contracts/src/Ownable.sol";
@@ -35,13 +35,13 @@ contract MixinAssets is
bytes4 constant internal ERC20_TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)"));
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
/// function optimally, and this function allows the ZRX to be withdrawn by owner. It may also be
/// used to withdraw assets that were accidentally sent to this contract.
/// @param assetData Byte array encoded for the respective asset proxy.
/// @param amount Amount of ERC20 token to withdraw.
function withdrawAsset(
bytes assetData,
bytes calldata assetData,
uint256 amount
)
external
@@ -84,7 +84,7 @@ contract MixinAssets is
// Transfer tokens.
// We do a raw call so we can check the success separate
// from the return data.
bool success = token.call(abi.encodeWithSelector(
(bool success,) = token.call(abi.encodeWithSelector(
ERC20_TRANSFER_SELECTOR,
msg.sender,
amount
@@ -93,7 +93,7 @@ contract MixinAssets is
success,
"TRANSFER_FAILED"
);
// Check return data.
// If there is no return data, we assume the token incorrectly
// does not return a bool. In this case we expect it to revert

View File

@@ -16,7 +16,7 @@
*/
pragma solidity ^0.4.24;
pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "./libs/LibConstants.sol";
@@ -144,6 +144,7 @@ contract MixinExchangeWrapper is
bytes memory wethAssetData = WETH_ASSET_DATA;
uint256 ordersLength = orders.length;
uint256 makerAssetFilledAmount = 0;
for (uint256 i = 0; i != ordersLength; i++) {
// We assume that asset being bought by taker is the same for each order.
@@ -175,7 +176,7 @@ contract MixinExchangeWrapper is
addFillResults(totalFillResults, singleFillResults);
// Stop execution if the entire amount of makerAsset has been bought
uint256 makerAssetFilledAmount = totalFillResults.makerAssetFilledAmount;
makerAssetFilledAmount = totalFillResults.makerAssetFilledAmount;
if (makerAssetFilledAmount >= makerAssetFillAmount) {
break;
}
@@ -192,7 +193,7 @@ contract MixinExchangeWrapper is
/// that at least zrxBuyAmount of ZRX is purchased (sometimes slightly over due to rounding issues).
/// It is possible that a request to buy 200 ZRX will require purchasing 202 ZRX
/// as 2 ZRX is required to purchase the 200 ZRX fee tokens. This guarantees at least 200 ZRX for future purchases.
/// The asset being sold by taker must always be WETH.
/// The asset being sold by taker must always be WETH.
/// @param orders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset.
/// @param zrxBuyAmount Desired amount of ZRX to buy.
/// @param signatures Proofs that orders have been created by makers.
@@ -230,7 +231,7 @@ contract MixinExchangeWrapper is
// of the Maker. In this case we want to overestimate the amount of takerAsset.
uint256 remainingWethSellAmount = getPartialAmountCeil(
orders[i].takerAssetAmount,
safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees
safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees
remainingZrxBuyAmount
);

View File

@@ -16,7 +16,7 @@
*/
pragma solidity ^0.4.24;
pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "./libs/LibConstants.sol";
@@ -58,7 +58,7 @@ contract MixinForwarderCore is
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
/// 5% of ETH value is reserved for paying fees to order feeRecipients (in ZRX) and forwarding contract feeRecipient (in ETH).
/// Any ETH not spent will be refunded to sender.
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
/// @param signatures Proofs that orders have been created by makers.
/// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
/// @param feeSignatures Proofs that feeOrders have been created by makers.
@@ -70,8 +70,8 @@ contract MixinForwarderCore is
bytes[] memory signatures,
LibOrder.Order[] memory feeOrders,
bytes[] memory feeSignatures,
uint256 feePercentage,
address feeRecipient
uint256 feePercentage,
address payable feeRecipient
)
public
payable
@@ -142,7 +142,7 @@ contract MixinForwarderCore is
/// @dev Attempt to purchase makerAssetFillAmount of makerAsset by selling ETH provided with transaction.
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
/// Any ETH not spent will be refunded to sender.
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
/// @param makerAssetFillAmount Desired amount of makerAsset to purchase.
/// @param signatures Proofs that orders have been created by makers.
/// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
@@ -156,8 +156,8 @@ contract MixinForwarderCore is
bytes[] memory signatures,
LibOrder.Order[] memory feeOrders,
bytes[] memory feeSignatures,
uint256 feePercentage,
address feeRecipient
uint256 feePercentage,
address payable feeRecipient
)
public
payable

View File

@@ -16,7 +16,7 @@
*/
pragma solidity ^0.4.24;
pragma solidity ^0.5.5;
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
import "./libs/LibConstants.sol";
@@ -30,7 +30,7 @@ contract MixinWeth is
{
/// @dev Default payabale function, this allows us to withdraw WETH
function ()
public
external
payable
{
require(
@@ -60,7 +60,7 @@ contract MixinWeth is
uint256 wethSoldExcludingFeeOrders,
uint256 wethSoldForZrx,
uint256 feePercentage,
address feeRecipient
address payable feeRecipient
)
internal
{
@@ -92,7 +92,7 @@ contract MixinWeth is
ethFee <= wethRemaining,
"INSUFFICIENT_ETH_REMAINING"
);
// Do nothing if no WETH remaining
if (wethRemaining > 0) {
// Convert remaining WETH to ETH

View File

@@ -16,18 +16,18 @@
*/
pragma solidity ^0.4.24;
pragma solidity ^0.5.5;
contract IAssets {
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
/// function optimally, and this function allows the ZRX to be withdrawn by owner. It may also be
/// used to withdraw assets that were accidentally sent to this contract.
/// @param assetData Byte array encoded for the respective asset proxy.
/// @param amount Amount of ERC20 token to withdraw.
function withdrawAsset(
bytes assetData,
bytes calldata assetData,
uint256 amount
)
external;

View File

@@ -16,7 +16,7 @@
*/
pragma solidity ^0.4.24;
pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "./IForwarderCore.sol";

View File

@@ -16,7 +16,7 @@
*/
pragma solidity ^0.4.24;
pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
@@ -29,7 +29,7 @@ contract IForwarderCore {
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
/// 5% of ETH value is reserved for paying fees to order feeRecipients (in ZRX) and forwarding contract feeRecipient (in ETH).
/// Any ETH not spent will be refunded to sender.
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
/// @param signatures Proofs that orders have been created by makers.
/// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
/// @param feeSignatures Proofs that feeOrders have been created by makers.
@@ -41,8 +41,8 @@ contract IForwarderCore {
bytes[] memory signatures,
LibOrder.Order[] memory feeOrders,
bytes[] memory feeSignatures,
uint256 feePercentage,
address feeRecipient
uint256 feePercentage,
address payable feeRecipient
)
public
payable
@@ -54,7 +54,7 @@ contract IForwarderCore {
/// @dev Attempt to purchase makerAssetFillAmount of makerAsset by selling ETH provided with transaction.
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
/// Any ETH not spent will be refunded to sender.
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
/// @param makerAssetFillAmount Desired amount of makerAsset to purchase.
/// @param signatures Proofs that orders have been created by makers.
/// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
@@ -68,8 +68,8 @@ contract IForwarderCore {
bytes[] memory signatures,
LibOrder.Order[] memory feeOrders,
bytes[] memory feeSignatures,
uint256 feePercentage,
address feeRecipient
uint256 feePercentage,
address payable feeRecipient
)
public
payable

View File

@@ -16,7 +16,7 @@
*/
pragma solidity ^0.4.24;
pragma solidity ^0.5.5;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
@@ -31,10 +31,10 @@ contract LibConstants {
bytes4 constant internal ERC20_DATA_ID = bytes4(keccak256("ERC20Token(address)"));
bytes4 constant internal ERC721_DATA_ID = bytes4(keccak256("ERC721Token(address,uint256)"));
uint256 constant internal MAX_UINT = 2**256 - 1;
uint256 constant internal PERCENTAGE_DENOMINATOR = 10**18;
uint256 constant internal PERCENTAGE_DENOMINATOR = 10**18;
uint256 constant internal MAX_FEE_PERCENTAGE = 5 * PERCENTAGE_DENOMINATOR / 100; // 5%
uint256 constant internal MAX_WETH_FILL_PERCENTAGE = 95 * PERCENTAGE_DENOMINATOR / 100; // 95%
// solhint-disable var-name-mixedcase
IExchange internal EXCHANGE;
IEtherToken internal ETHER_TOKEN;

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