Compare commits

...

1747 Commits

Author SHA1 Message Date
fabioberger
3b9d84fa58 Publish
- @0x/contracts-asset-proxy@2.3.0-beta.1
 - @0x/contracts-coordinator@2.1.0-beta.1
 - @0x/contracts-dev-utils@0.1.0-beta.1
 - @0x/contracts-erc1155@1.2.0-beta.1
 - @0x/contracts-erc20@2.3.0-beta.1
 - @0x/contracts-erc721@2.2.0-beta.1
 - @0x/contracts-exchange-forwarder@3.1.0-beta.1
 - @0x/contracts-exchange-libs@3.1.0-beta.1
 - @0x/contracts-exchange@2.2.0-beta.1
 - @0x/contracts-extensions@4.1.0-beta.1
 - @0x/contracts-integrations@1.0.1
 - @0x/contracts-multisig@3.2.0-beta.1
 - @0x/contracts-staking@1.1.0-beta.1
 - @0x/contracts-test-utils@3.2.0-beta.1
 - @0x/contracts-tests@0.0.2
 - @0x/contracts-utils@3.3.0-beta.1
 - 0x.js@8.0.0-beta.0
 - @0x/abi-gen-wrappers@5.4.0-beta.1
 - @0x/abi-gen@4.4.0-beta.1
 - @0x/assert@2.2.0-beta.1
 - @0x/asset-buyer@6.2.0-beta.1
 - @0x/asset-swapper@2.1.0-beta.1
 - @0x/base-contract@5.5.0-beta.1
 - @0x/connect@5.1.0-beta.1
 - @0x/contract-addresses@3.3.0-beta.2
 - @0x/contract-artifacts@2.3.0-beta.2
 - @0x/contract-wrappers@12.2.0-beta.1
 - @0x/contracts-gen@1.1.0-beta.1
 - @0x/dev-utils@2.4.0-beta.1
 - ethereum-types@2.2.0-beta.1
 - @0x/instant@1.0.33
 - @0x/json-schemas@4.1.0-beta.1
 - @0x/migrations@4.4.0-beta.1
 - @0x/monorepo-scripts@1.0.39
 - @0x/order-utils@8.5.0-beta.1
 - @0x/orderbook@0.1.0-beta.1
 - @0x/sol-compiler@3.2.0-beta.1
 - @0x/sol-coverage@3.1.0-beta.1
 - @0x/sol-doc@2.1.0-beta.1
 - @0x/sol-profiler@3.2.0-beta.1
 - @0x/sol-resolver@2.1.0-beta.1
 - @0x/sol-trace@2.1.0-beta.1
 - @0x/sol-tracing-utils@6.1.0-beta.1
 - @0x/sra-spec@2.1.0-beta.1
 - @0x/subproviders@5.1.0-beta.1
 - @0x/testnet-faucets@1.0.89
 - @0x/tslint-config@3.1.0-beta.1
 - @0x/types@2.5.0-beta.1
 - @0x/typescript-typings@4.4.0-beta.1
 - @0x/utils@4.6.0-beta.1
 - @0x/web3-wrapper@6.1.0-beta.1
2019-11-07 20:43:12 +00:00
fabioberger
6fd96a6fd7 Updated CHANGELOGS & MD docs 2019-11-07 20:42:58 +00:00
fabioberger
c93b02d55e Update DevUtils artifacts in contract-artifacts 2019-11-07 19:33:12 +00:00
fabioberger
568f87d5eb Add CHANGELOG entry about the updated DevUtils contract addresses 2019-11-07 19:24:07 +00:00
fabioberger
49ad0f0d54 Update devUtils contract addresses 2019-11-07 19:22:28 +00:00
fabioberger
0e642f59e1 Fix contract-addresses version in 0x.js 2019-11-07 19:00:26 +00:00
fabioberger
7c5730fb03 Update dep versions that were accidentally published 2019-11-07 18:11:40 +00:00
fabioberger
45f0f755ab Merge branch 'development' of github.com:0xProject/0x-monorepo into development 2019-11-07 18:07:23 +00:00
fabioberger
1ef2913c5b Update all CHANGELOGs to prep for publish 2019-11-07 18:07:15 +00:00
F. Eugene Aumson
fecbf220b6 Remove --serial from monorepo test:contracts (#2320) 2019-11-07 13:03:55 -05:00
fabioberger
17a5f05cf3 Make contract-test package private 2019-11-07 18:02:38 +00:00
Xianny
6a852ab0ed Replace assetDataUtils with DevUtilsContract wherever possible (#2304)
* Replace assetDataUtils with DevUtilsContract wherever possible

Does not replace from @0x/instant and some @0x/order-utils uses

* Add revertIfInvalidAssetData to LibAssetData

This is needed to replace `assetDataUtils.decodeAssetDataOrThrow`.
Because it's used in packages and not only contracts, we should wait
to deploy the updated contract so we can update `@0x/contract-artifacts`,
`@0x/abi-gen-wrappers`, and `@0x/contract-wrappers` first.

* remove usages of signatureUtils

* fix test for  optimised encoding

* refactor @0x/contracts-integrations

* update changelogs

* Move @0x/contracts-dev-utils from devDependencies to dependencies
It is exported as part of the package
2019-11-06 19:40:20 -08:00
Jacob Evans
ec26cff656 Fix contract-addresses CHANGELOG (prettier) 2019-11-07 08:48:48 +11:00
xianny
cdd34a1214 Updated CHANGELOGS & MD docs ONLY for pkgs that made it to npmjs (partial publish) 2019-11-06 12:50:58 -08:00
F. Eugene Aumson
857a4042ef abi-gen: Include templates in published tarball (#2315)
* abi-gen: Include templates in published tarball

* abi-gen: update CHANGELOG

* abi-gen/package.json: explicitly include code

Apparently when you include a "files" section, it by default only
includes the code directly referenced by the package.json.  (For this
package, it was including the lib/src/index.js referenced by "main", and
the bin/abi-gen.js referenced by "bin", but no other *.js files, nor any
*.d.ts files.)
2019-11-06 02:39:35 -05:00
F. Eugene Aumson
f51c80adb2 Change all instances of networkId to chainId (#2313)
* abi-gen/test: recompile contract fixtures for 3.0

It seems this hadn't been done since the merge with the 3.0 branch.

* Sync `monorepo$ yarn test` exclusions to CI config

* sra-spec: correct typo

* contract-wrappers: TODO after coord.-server update

* utils: fix typo in comment

* Refactor networkId to chainId everywhere

* Update CHANGELOGs
2019-11-06 01:18:55 -05:00
F. Eugene Aumson
e61f23d001 Migrate Python libraries to v3 (#2284)
* .gitignore migrations/0x_ganache_snapshot

* .gitignore new-ish Python contract wrappers

These should have been added back when we started generating these
wrappers.

* rm superfluous contract artifact in Python package

All of the contract artifacts were removed from the Python package
recently, because now they're copied from the monorepo/packages area as
an automated build step.  Somehow this one artifact slipped through the
cracks.

* Eliminate circular dependency

This was preventing the Exchange wrapper from ever importing its
validator!

* Improve output of monorepo-level parallel script

- Capture stderr (and have it included in stdout) so that it doesn't
leak onto the console for commands that didn't actually fail.

- Include all error output in the Exception object (eliminate print
statement).

* Silence new versions of linters

Newer versions care about this stuff.  Old versions didn't, and we don't
either.

* Support Rich Reverts via Web3.py middleware

* Fix bug in generated wrappers' bytes handling

`bytes.fromhex(bytes.decode('utf-8')` is just plain wrong.  It would
work for some cases, but is not working when trying to fill orders with
the latest Exchange contract.

* Migrate to Exchange v3

* Fix typo in DevUtils documentation

* Include new contracts in docs

* Re-enable Python checks in CI

* Accept strings for bytes

* Fix CircleCI build artifacts for gen'd python

I swear the previous way was working before, but it wasn't working now,
so this fixes it.

* Accept a provider OR a Web3 object

In various places.  This allows the caller to install middleware (which
in web3.py is installed on a Web3 object, not on a provider) before
executing any RPC calls, which is important for the case where one wants
to produce signatures locally before submitting to a remote node.

* wrapper base: don't assume there are accounts

* Eliminate some inline linter directives

* make CHANGELOGs be REVERSE chronological

* Update CHANGELOG entries and bump version numbers

* @0x/contract-addresses: Put addr's in JSON, not TS

This allows easier consumption by other languages.  (Specifically, it
eliminates the overhead of keeping the Python addresses package in sync
with the TypeScript one.)

* sra_client.py: incl. docker in `./setup.py clean`

* sra_client.py: Migrate to protocol v3

Removed script that existed only to exclude runs of sra_client builds
(parallel_without_sra_client).  Now `parallel` is used by CI,
re-including sra_client in CI checks.

* abi-gen/templates/Py: clarify if/else logic

In response to
https://github.com/0xProject/0x-monorepo/pull/2284#discussion_r342200906

* sra_client.py: Update CHANGELOG and bump version

* contract_addresses/setup.py: rm unnecessary rm

* json_schemas.py: corrections to dev dependencies

* In tests against deployment, also run doctests

* contract_wrappers example: rm xtra Order attribute

Thanks to @steveklebanoff for catching this.
https://github.com/0xProject/0x-monorepo/pull/2284#pullrequestreview-312065368
2019-11-05 23:04:29 -05:00
Greg Hysz
cbe4c4fbf9 Merge pull request #2319 from 0xProject/fix/development/blockTimestampTooLowNonDeterministicBug
Fix development
2019-11-05 17:23:18 -08:00
xianny
deffdabc30 Revert "Updated CHANGELOGS & MD docs"
This reverts commit f65d8cc325.
2019-11-05 17:06:05 -08:00
xianny
8811a5387a Revert "Publish"
This reverts commit 9336d4e545.
2019-11-05 17:05:58 -08:00
xianny
9336d4e545 Publish
- @0x/contracts-asset-proxy@2.3.0-beta.1
 - @0x/contracts-coordinator@2.1.0-beta.1
 - @0x/contracts-dev-utils@0.1.0-beta.1
 - @0x/contracts-erc1155@1.2.0-beta.1
 - @0x/contracts-erc20@2.3.0-beta.1
 - @0x/contracts-erc721@2.2.0-beta.1
 - @0x/contracts-exchange-forwarder@3.1.0-beta.1
 - @0x/contracts-exchange-libs@3.1.0-beta.1
 - @0x/contracts-exchange@2.2.0-beta.1
 - @0x/contracts-extensions@4.1.0-beta.1
 - @0x/contracts-integrations@1.0.1
 - @0x/contracts-multisig@3.2.0-beta.1
 - @0x/contracts-staking@1.1.0-beta.1
 - @0x/contracts-test-utils@3.2.0-beta.1
 - @0x/contracts-tests@0.0.2
 - @0x/contracts-utils@3.3.0-beta.1
 - 0x.js@7.1.0-beta.1
 - @0x/abi-gen-wrappers@5.4.0-beta.1
 - @0x/abi-gen@4.4.0-beta.1
 - @0x/assert@2.2.0-beta.1
 - @0x/asset-buyer@6.2.0-beta.1
 - @0x/asset-swapper@2.1.0-beta.1
 - @0x/base-contract@5.5.0-beta.1
 - @0x/connect@5.1.0-beta.1
 - @0x/contract-addresses@3.3.0-beta.1
 - @0x/contract-artifacts@2.3.0-beta.1
 - @0x/contract-wrappers@12.2.0-beta.1
 - @0x/contracts-gen@1.1.0-beta.1
 - @0x/dev-utils@2.4.0-beta.1
 - ethereum-types@2.2.0-beta.1
 - @0x/instant@1.0.33
 - @0x/json-schemas@4.1.0-beta.1
 - @0x/migrations@4.4.0-beta.1
 - @0x/monorepo-scripts@1.0.39
 - @0x/order-utils@8.5.0-beta.1
 - @0x/orderbook@0.1.0-beta.1
 - @0x/sol-compiler@3.2.0-beta.1
 - @0x/sol-coverage@3.1.0-beta.1
 - @0x/sol-doc@2.1.0-beta.1
 - @0x/sol-profiler@3.2.0-beta.1
 - @0x/sol-resolver@2.1.0-beta.1
 - @0x/sol-trace@2.1.0-beta.1
 - @0x/sol-tracing-utils@6.1.0-beta.1
 - @0x/sra-spec@2.1.0-beta.1
 - @0x/subproviders@5.1.0-beta.1
 - @0x/testnet-faucets@1.0.89
 - @0x/tslint-config@3.1.0-beta.0
 - @0x/types@2.5.0-beta.1
 - @0x/typescript-typings@4.4.0-beta.1
 - @0x/utils@4.6.0-beta.1
 - @0x/web3-wrapper@6.1.0-beta.1
2019-11-05 16:58:14 -08:00
xianny
f65d8cc325 Updated CHANGELOGS & MD docs 2019-11-05 16:58:00 -08:00
Greg Hysen
68656c4083 Fixes intermittent test failure by removing block timestamp contraints from staking scheduler tests 2019-11-05 16:57:37 -08:00
Greg Hysz
44793a9cf9 Merge pull request #2316 from 0xProject/tests/3.0/StakingMixinCumulativeRewardsUnitTEsts
Unit tests for MixinCumulativeRewards
2019-11-05 16:00:52 -08:00
Greg Hysen
2d0ad6f181 Updated staking changelog 2019-11-05 15:32:35 -08:00
Greg Hysen
a7f0717afb Unit tests for MixinCumulativeRewards 2019-11-05 15:32:04 -08:00
Greg Hysz
a9022352e7 Merge pull request #2314 from 0xProject/tests/3.0/MixinSchedulerUnitTests
Unit tests for MixinScheduler
2019-11-05 15:27:20 -08:00
Greg Hysen
9b2231ed24 Improved readability on some tests + updated staking changelog 2019-11-05 14:59:55 -08:00
Greg Hysen
c123200f38 Unit tests for MixinScheduler 2019-11-04 15:44:46 -08:00
James Towle
3c6c4128a6 Merge pull request #2294 from 0xProject/refactor/integration-tests/wrapper-functions
Refactor/integration tests/wrapper functions
2019-11-04 14:46:11 -08:00
Lawrence Forman
47e050cbaf Merge pull request #2312 from 0xProject/feat/contracts/staking/MixinStakingPoolRewards-unit-tests
MixinStakingPoolRewards unit tests
2019-11-04 17:19:03 -05:00
Alex Towle
62d15117c5 @0x:contracts-integrations Removed the dependency on number_utils from staking 2019-11-04 14:16:43 -08:00
Lawrence Forman
fb8360edfd Merge pull request #2311 from 0xProject/fix/contracts/staking/LibFixedMath-overflow-pt-2
Fix `LibFixedMath._mul()` overflow
2019-11-04 12:49:20 -05:00
Alex Towle
e557f2fb48 @0x:contracts-integrations Added decimal.js to dependencies so that number_utils can be used 2019-11-04 09:39:00 -08:00
Lawrence Forman
c957b48281 @0x/contracts-staking: Run prettier. 2019-11-04 11:10:07 -05:00
Lawrence Forman
c15c5e12b0 @0x/contracts-staking: Fix event name collision in MixinStakingPoolRewards unit tests. 2019-11-04 11:09:21 -05:00
Lawrence Forman
15c3c8074c @0x/contracts-staking: Add separate unit tests for withdrawDelegatorRewards() and _withdrawAndSyncDelegatorRewards(). 2019-11-04 10:43:37 -05:00
Lawrence Forman
cba72c811d @0x/contracts-staking: Add _computePoolRewardsSplit() tests to MixinStakingPoolRewards unit tests. 2019-11-04 10:43:37 -05:00
Lawrence Forman
28a2e56003 @0x/contracts-staking: Add more MixinStakingPoolRewards unit tests. 2019-11-04 10:43:37 -05:00
Lawrence Forman
8c4c3d56c6 @0x/contracts-staking: Create MixinStakingPoolRewards unit tests. 2019-11-04 10:43:37 -05:00
Alex Towle
911fcc0bed @0x:contracts-integrations Addressed review comments from @mzhu 2019-11-01 17:16:17 -07:00
Alex Towle
55fd16ccf1 @0x:contracts-integrations Addressed review comments from @dorothy-zbornak 2019-11-01 12:04:24 -07:00
Lawrence Forman
4e05e41f7f Merge pull request #2309 from 0xProject/feat/contracts/utils/LibERC20Token
LibERC20Token
2019-11-01 14:57:10 -04:00
Alex Towle
ebab80cff7 @0x:contracts-integrations Fixed test issues 2019-11-01 11:22:12 -07:00
Alex Towle
91cb162662 @0x:contracts-integrations Added tests for weth protocol fees 2019-11-01 11:22:12 -07:00
Alex Towle
fa26f8de51 @0x:contracts-integrations Refactored to reduce redundancy 2019-11-01 11:22:12 -07:00
Alex Towle
26602ac2db @0x:contracts-integrations Added assertions for events in all wrapper functions 2019-11-01 11:22:12 -07:00
Alex Towle
0b8af181d8 @0x:contracts-integrations Refactored the wrapper tests to use newer tools 2019-11-01 11:22:12 -07:00
Alex Towle
19d661d324 @0x:contracts-integrations Started to refactor the wrapper tests 2019-11-01 11:22:12 -07:00
Alex Towle
7d29b36246 @0x:contracts-integrations Moved the wrapper tests into the integrations package 2019-11-01 11:21:52 -07:00
Lawrence Forman
8ba7b95e86 @0x/contracts-utils: Move LibERC20Token out.
`@0x/contracts-erc20`: Move `LibERC20Token` in.
`@0x/contracts-erc20`: Use `LibBytes` and `LibRichErrors` in `LibERC20Token`.
`@0x/contracts-erc20`: Use `verifyEventsFromLogs` in `LibERC20Token` unit tests.
2019-11-01 13:58:22 -04:00
Lawrence Forman
30c72daed5 @0x/order-utils: Remove TransferFailedError from ForwarderRevertErrors (for real this time). 2019-11-01 13:36:07 -04:00
Lawrence Forman
575cb99839 @0x/contracts-utils: Update comments in LibERC20Token. 2019-11-01 13:36:07 -04:00
Lawrence Forman
0c064bf85b Update changelogs. 2019-11-01 13:36:07 -04:00
Lawrence Forman
0f3610c92a @0x/contracts-asset-proxy: Use LibERC20Token in UniswapBridge and Eth2DaiBridge. 2019-11-01 13:36:07 -04:00
Lawrence Forman
c8ef10baaf @0x/contracts-utils: Use simple assembly instead of abi.decode() in LibERC20Token._callWithOptionalBooleanResult().
`@0x/contracts-exchange-forwarder`: Use `LibERC20Token` in `MixinAssets`.
`@0x/order-utils`: Remove `TransferFailedError` from `ForwarderRevertErrors`.
2019-11-01 13:36:07 -04:00
Lawrence Forman
16dc73bd1e @0x/contracts-utils: Add LibERC20Token. 2019-11-01 13:36:07 -04:00
Lawrence Forman
4f56d68689 @0x/contracts-staking: Fix overflow w/ LibFixedMath._mul(-1, -2*255). 2019-11-01 13:35:23 -04:00
Greg Hysz
8e6d92cad5 Merge pull request #2310 from 0xProject/tests/3.0/StakingProxyUnitTests
Staking Proxy Unit Tests + Fallback Reverts if No Staking Contract
2019-11-01 10:26:54 -07:00
Greg Hysen
3a1c464543 Readability improvements to Staking Proxy unit tests + one extra case 2019-11-01 09:59:17 -07:00
Greg Hysen
a0c2f6b7b4 Updated Staking changelog 2019-10-31 18:25:33 -07:00
Greg Hysen
7bfbf0ad3a Staking Proxy unit tests + Staking Proxy fallback reverts if no staking contract is attached 2019-10-31 18:22:49 -07:00
mzhu25
82ee6750c7 Merge pull request #2307 from 0xProject/fix/integration-tests/tslint
`@0x/contracts-integrations`: Enable tslint and fix lint errors
2019-10-31 16:23:35 -07:00
mzhu25
c37fc30c55 Merge pull request #2302 from 0xProject/feature/integration-tests/fillOrder
`@0x/contracts-integrations`: fillOrder integration tests
2019-10-31 16:20:07 -07:00
Michael Zhu
09d13b2bfa default before/after in FunctionAssertion 2019-10-31 15:49:12 -07:00
Michael Zhu
af0de72bc3 address comments 2019-10-31 15:30:15 -07:00
Michael Zhu
43e32f6a1a fix other lint errors 2019-10-31 15:30:15 -07:00
Michael Zhu
e9e6452890 add tslint.json to package and update actor mixins 2019-10-31 15:28:02 -07:00
Michael Zhu
5f699b0c47 add test for weth protocol fees 2019-10-31 15:27:39 -07:00
Michael Zhu
bf18b86f9f address comments 2019-10-31 15:27:39 -07:00
Michael Zhu
56f7dd7538 fix deployment_manager_test 2019-10-31 15:27:39 -07:00
Michael Zhu
7aa88307f6 Flesh out fillOrder integration tests 2019-10-31 15:27:39 -07:00
James Towle
8aa69233e0 Merge pull request #2305 from 0xProject/sandstorm/framework/function_assertion_set
Function Assertion Sets
2019-10-31 14:07:57 -07:00
James Towle
e843333918 Merge pull request #2308 from 0xProject/fix/unblock-kroeger/add-contract-artifacts
`@0x:artifacts` Added the Staking and StakingProxy artifacts
2019-10-31 12:42:43 -07:00
Alex Towle
133a4dc4e1 @0x:contract-artifacts Trimmed artifacts and ran prettier 2019-10-31 10:21:40 -07:00
Alex Towle
c7945a542e @0x:abi-gen-wrappers Added exports 2019-10-31 10:18:41 -07:00
Alex Towle
b4e00baa07 @0x:artifacts Added the Staking and StakingProxy artifacts 2019-10-31 10:18:40 -07:00
Alex Towle
dde570706a @0x:contracts-integrations Put final cleaning touches on the function assertion set 2019-10-30 13:26:29 -07:00
Alex Towle
0b3e3ab990 @0x:contracts-integrations Addressed more review comments 2019-10-30 11:11:55 -07:00
Alex Towle
205c895d75 @0x:contracts-integrations Added better documentation to FunctionAssertions 2019-10-29 23:19:28 -07:00
Alex Towle
6402d29dd4 @0x:contracts-integrations Added collections of function assertions 2019-10-29 14:51:01 -07:00
mzhu25
dc18999931 Merge pull request #2293 from 0xProject/refactor/integrations/forwarder-tests
Refactor and move Forwarder tests to integrations package
2019-10-29 13:04:59 -07:00
Michael Zhu
43f8101d0b address comments 2019-10-29 11:26:56 -07:00
Michael Zhu
3d56c06ff3 Move Forwarder test to integrations; update to use new framework 2019-10-29 11:26:56 -07:00
Lawrence Forman
db9be73fec Merge pull request #2292 from 0xProject/feat/staking/MixinStakeBalances-unit-tests
Add MixinStakeBalances unit tests.
2019-10-29 08:11:59 -04:00
Lawrence Forman
a02892cbc8 @0x/contracts-staking: Remove duplicated test case in MixinStakeBalances unit tests. 2019-10-29 07:37:06 -04:00
Lawrence Forman
49c67fbb18 @0x/contracts-staking: Remove unused lodash import and only modifier from MixinStakeBalances unit tests. 2019-10-29 07:37:06 -04:00
Lawrence Forman
6f2e79208a @0x/contracts-staking: Add MixinStakeBalances unit tests. 2019-10-29 07:37:06 -04:00
Amir Bandeali
ceb3ba4116 Merge pull request #2296 from 0xProject/feat/3.0/testnet-migrations-2
Update 3.0 testnet migrations and addresses
2019-10-28 21:29:03 -07:00
Greg Hysz
08d4f1402f Merge pull request #2301 from 0xProject/fix/3.0/removeLibProxy
Removed LibProxy and inlined proxy call in StakingProxy.
2019-10-28 20:00:24 -07:00
Amir Bandeali
77fa97f259 Update DevUtils, Forwarder, and Coordinator addresses for each testnet 2019-10-28 17:40:50 -07:00
Amir Bandeali
3ac5d9add5 Add DevUtils, Forwarder, and Coordinator to testnet migrations 2019-10-28 17:40:45 -07:00
Amir Bandeali
cab89f312a Update CHANGELOG 2019-10-28 16:55:54 -07:00
Amir Bandeali
8972475389 Update testnet migrations and verifications 2019-10-28 16:55:54 -07:00
Amir Bandeali
330f2d54e2 Update contract-addresses with new testnet deployments 2019-10-28 16:55:54 -07:00
Greg Hysen
9c181f09ba Removed LibProxy and inlined proxy call in StakingProxy. 2019-10-28 16:42:52 -07:00
Amir Bandeali
011ecb8f4b Merge pull request #2297 from 0xProject/fix/multisig/allow-tx-to-be-over-confirmed
Allow transactions to be over confirmed without resetting the confirmation time
2019-10-28 12:49:19 -07:00
Amir Bandeali
bc2a9beb14 Merge pull request #2295 from 0xProject/feat/staking/remove-read-only-mode
Remove read-only mode and associated code
2019-10-28 12:02:10 -07:00
Amir Bandeali
091f5ed8b8 Allow transactions to be over confirmed without resetting the confirmation time 2019-10-28 10:45:17 -07:00
F. Eugene Aumson
ea9f535a7c contract_addresses.py: Add DevUtils contract (#2150)
* contract_addresses.py: Add DevUtils

* Update __init__.py

* Remove whitespace to satisfy linters
2019-10-28 13:32:24 -04:00
Amir Bandeali
f246314b1d Update default alpha from 1/2 to 2/3 2019-10-27 16:53:57 -07:00
Amir Bandeali
cdfd62a296 Fix reentrancy tests 2019-10-27 14:23:19 -07:00
Amir Bandeali
dcff7d511b Add tests for detachProtocolFeeCollector 2019-10-27 11:41:06 -07:00
Amir Bandeali
16a5475d24 Add detachProtocolFeeCollector function (in order to have a separate timelock for detaching) 2019-10-27 11:40:28 -07:00
Amir Bandeali
42468c3fa2 Remove read-only proxy from contract addresses and migrations 2019-10-27 11:12:22 -07:00
Amir Bandeali
9312d5d9f7 remove read-only mode related code from integrations 2019-10-27 11:12:22 -07:00
Amir Bandeali
33a0c22021 Remove tests related to read-only mode 2019-10-27 11:12:22 -07:00
Amir Bandeali
58e9c70203 Remove read-only mode related functions, storage variables, and contracts 2019-10-27 11:12:16 -07:00
F. Eugene Aumson
0067f10a6a @0x/utils: fix wrong RPC method in getChainIdAsync() (#2270)
It was using net_version, but it should be using the eth_chainId method
introduced in EIP-695.  I'm not sure whether/how the network ID differs
from the chain ID on mainnet and the testnets, but in Ganache in
particular, the network ID is 50 while the chain ID is 1337, and this
difference was causing problems for Python tests.  Specifically, the
Web3.py interface `Web3.eth.chainId` invokes the eth_chainId method, and
the result feeds into the order hash, which wasn't lining up with the
non-Python side of things.
2019-10-25 21:08:31 -04:00
Lawrence Forman
59210f5e5e Merge pull request #2287 from 0xProject/feat/staking/MixinStakingPool-unit-tests
Add MixinStakingPool unit tests.
2019-10-25 11:59:50 -04:00
Lawrence Forman
1c695b2759 Rebase onto 3.0 2019-10-25 10:56:03 -04:00
Lawrence Forman
c7222c17ae @0x/contracts-test-utils: prettier 2019-10-25 10:55:03 -04:00
Lawrence Forman
0f237d22f9 @0x/contracts-test-utils: Refactor verifyEvents() to just use verifyEventsFromLogs(). 2019-10-25 10:55:03 -04:00
Lawrence Forman
b1b1162b60 @0x/contracts-staking: Add MixinStakingPool unit tests. 2019-10-25 10:55:03 -04:00
Lawrence Forman
6ee1605a77 @0x/contracts-test-utils: Add verifyEventsFromLogs(). 2019-10-25 10:54:38 -04:00
Greg Hysz
a22b2e7a9f Merge pull request #2290 from 0xProject/fix/3.0/updatedInterfaces
Created IZrxVaultBackstop and updated IStaking.
2019-10-25 06:33:18 -07:00
Greg Hysz
86ed32a007 Merge pull request #2288 from 0xProject/fix/3.0/minorStakingReadability
Replaced `protocolFeePaid` -> `protocolFeeAmount`
2019-10-25 06:19:20 -07:00
Greg Hysen
8e8ea6a3ab Created IZrxVaultBackstop and updated IStaking. 2019-10-24 15:58:51 -07:00
Greg Hysen
cc7452da8f Replaced protocolFeePaid -> protocolFeeAmount. Changed some wording in comments. 2019-10-24 15:58:18 -07:00
Amir Bandeali
06715201a7 Merge pull request #2283 from 0xProject/fix/3.0/rename-bridge-withdraw-to
Rename `withdrawTo` to `bridgeTransferFrom`
2019-10-23 10:15:08 -07:00
Amir Bandeali
281658ba34 Rename withdrawTo to bridgeTransferFrom 2019-10-23 09:42:37 -07:00
Lawrence Forman
f192648c76 Merge pull request #2279 from 0xProject/fix/3.0-audit/staking/assert-valid-params-in-MixinParams
Assert storage params when calling `MixinParams.setParams()`.
2019-10-23 05:11:10 -04:00
Lawrence Forman
07e1d502e7 @0x/contracts-staking: Update changelog. 2019-10-23 04:40:47 -04:00
Lawrence Forman
703e890918 @0x/contracts-staking: Call StakingProxy.assertValidStorageParams() in MixinParams.setParams() 2019-10-23 04:40:47 -04:00
mzhu25
096950729e Merge pull request #2275 from 0xProject/refactor/integrations/coordinator-tests-part2
Coordinator test refactor [2/2]
2019-10-22 17:37:21 -07:00
Michael Zhu
8869d79c68 rebase 2019-10-22 17:05:08 -07:00
Michael Zhu
752dd04546 address comments 2019-10-22 17:05:08 -07:00
Michael Zhu
3e5d166ec4 moving away from extending DeploymentManager in case we want to deploy multiple extensions alongside one another 2019-10-22 17:05:08 -07:00
Michael Zhu
64bc1b0990 update coordinator tests to use deployment manager, balance stores, actor mixins 2019-10-22 17:05:08 -07:00
Michael Zhu
548b0db6ea coordinator deployment manager 2019-10-22 17:05:08 -07:00
Greg Hysz
c9607e8b2c Merge pull request #2280 from 0xProject/fix/3.0/handleNopInMoveStake
Force no-op when moving stake, in some scenarios
2019-10-22 16:51:46 -07:00
Greg Hysen
c676ecb8cf Force no-op when moving zero stake or moving from undelegated to undelegated. 2019-10-22 15:39:24 -07:00
James Towle
39804fdc83 Merge pull request #2281 from 0xProject/fix/ci/10-22-2019
`CI` Fix build failure
2019-10-22 15:20:24 -07:00
Alex Towle
1a1dc89454 CI Fix build failure 2019-10-22 14:53:13 -07:00
James Towle
e427698956 Merge pull request #2252 from 0xProject/feature/sandstorm/function-assertions
Initial Sandstorm Framework
2019-10-22 13:45:42 -07:00
Greg Hysz
575af6b6e8 Merge pull request #2278 from 0xProject/fix/3.0/removeProtocolFeeZeroAssertion
Remove assertion that protocol fee != zero
2019-10-22 13:24:59 -07:00
Alex Towle
3a1fc9ee5f @0x:contracts-integrations Fixed package after rebase 2019-10-22 13:15:01 -07:00
mzhu25
1237c7d479 Merge pull request #2277 from 0xProject/fix/3.0/rmeove-staking-fallback
Remove payable fallback from Staking.sol
2019-10-22 12:46:13 -07:00
Greg Hysen
c44e16a88f Removed assertion that protocol fee != 0 from staking contract. 2019-10-22 12:42:04 -07:00
Greg Hysz
06c180475e Merge pull request #2276 from 0xProject/cleanup/staking/finalizationDataStructures
Refactored finalization state.
2019-10-22 12:37:50 -07:00
Michael Zhu
74a2c3a199 Remove payable fallback from Staking.sol 2019-10-22 12:15:07 -07:00
Greg Hysen
9ac715f99d Protocol fee amount is not enforced by staking contract 2019-10-22 12:10:34 -07:00
Greg Hysen
22e39f782f Some (more) readability improvements and minor optimizations to staking finalization. 2019-10-22 12:09:18 -07:00
Alex Towle
f5a6b84fa3 CI: Added a seperate workflow for contracts/integrations 2019-10-22 12:07:50 -07:00
Alex Towle
718407ba6f @0x:contracts-integrations Switched to object destructuring in the function assertion unit test 2019-10-22 12:07:50 -07:00
Alex Towle
e603a81a46 @0x:contracts-integrations Simplified the tests 2019-10-22 12:07:50 -07:00
Alex Towle
03e35846fb @0x:contracts-integrations Removed the Cache 2019-10-22 12:07:50 -07:00
Alex Towle
c87364f86b @0x:contracts-integrations Addressed more review feedback 2019-10-22 12:07:50 -07:00
Alex Towle
a794a33551 @0x:contracts-integrations Addressed review comments 2019-10-22 12:06:38 -07:00
Alex Towle
494b437f1a @0x:contracts-integrations Renamed some functions in Address Manager 2019-10-22 12:04:47 -07:00
Alex Towle
92b80fc436 @0x:contracts-integrations Improved the caches 2019-10-22 12:04:47 -07:00
Alex Towle
d66101cd9d @0x:contracts-integrations Added unit tests for FunctionAssertion 2019-10-22 12:04:47 -07:00
Alex Towle
89ae04803f @0x:contract-integrations Added the integrations package to CI 2019-10-22 12:01:54 -07:00
Alex Towle
be95bce4cd @0x:contract-integrations Move caches to a new file 2019-10-22 12:01:30 -07:00
Alex Towle
01aee08c02 @0x:contracts-integrations Wrote a simple integration test and AddressManager 2019-10-22 12:01:30 -07:00
Alex Towle
6cba9fd77f @0x/contracts-integrations Created the FunctionAssertion class and examples 2019-10-22 11:59:17 -07:00
mzhu25
673d45361f Merge pull request #2273 from 0xProject/refactor/integrations/coordinator-tests
Coordinator test refactor [1/2] + actor mixin pattern
2019-10-22 11:37:02 -07:00
Greg Hysen
d91a7fc663 Some readability improvements and minor optimizations to staking finalization. 2019-10-22 11:02:25 -07:00
Greg Hysen
ce8fd44234 Removed lingering references to stale terminology ("active pools") 2019-10-22 11:02:25 -07:00
Greg Hysen
6617ad9531 Refactored finalization state.
1. Removes state variables:
   - totalWeightedStakeThisEpoch
   - totalFeesCollectedThisEpoch
   - numActivePoolsThisEpoch

2. No longer indexes by epoch % 2

3. Renamed event StakingPoolActivated → StakingPoolEarnedRewards.

4. Renamed structs:
   - ActivePool → PoolStats. This holds stats for a pool that earned rewards.
   - UnfinalizedState → AggregatedStats. This aggregates stats from the former struct.
2019-10-22 11:02:25 -07:00
Amir Bandeali
10f8051835 Merge pull request #2274 from 0xProject/feat/staking/separate-function-logic
Separate finalization from withdrawing rewards
2019-10-22 10:36:04 -07:00
Amir Bandeali
e7dc7167d0 Sync delegatedStakeToPoolByOwner whenever _withdrawAndSyncDelegatorRewards is called 2019-10-22 09:38:18 -07:00
Amir Bandeali
359b804001 Add test for withdrawing rewards before epoch is finalized 2019-10-21 22:27:06 -07:00
Amir Bandeali
fd9084b345 Add PoolNotFinalizedError rich revert 2019-10-21 22:27:06 -07:00
Amir Bandeali
44dac2cd80 Fix tests that assume touching stake will finalize pool 2019-10-21 22:27:06 -07:00
Amir Bandeali
a66ea2bf74 Assert that pool has been finalized in _withdrawAndSyncDelegatorRewards rather than calling finalizePool 2019-10-21 22:27:06 -07:00
Amir Bandeali
a362e9d2d8 Use safeMath where possible 2019-10-21 22:27:06 -07:00
Amir Bandeali
1885957bd3 Update tests to start at epoch 1 2019-10-21 22:27:06 -07:00
Amir Bandeali
1a409c3731 Initialize currentEpoch at 1 instead of 0 2019-10-21 22:27:06 -07:00
Amir Bandeali
7b7c64fc6a Add assertion function that checks if pool was finalized last epoch 2019-10-21 22:27:06 -07:00
Michael Zhu
102fcd3fb8 export actor classes 2019-10-21 11:17:53 -07:00
Michael Zhu
566e05aea4 typo 2019-10-21 11:17:53 -07:00
Michael Zhu
f014370531 document mixin constructor params 2019-10-21 11:17:53 -07:00
Michael Zhu
dfbbe9daa2 address comments 2019-10-21 11:17:53 -07:00
Michael Zhu
6b653fb00d prettier gdi 2019-10-21 11:17:53 -07:00
Michael Zhu
21cf2319d5 rename some stuff 2019-10-21 11:17:53 -07:00
Michael Zhu
4210477e71 Introduce actor mixin pattern 2019-10-21 11:17:53 -07:00
Michael Zhu
93b02e93b9 juggling some files around 2019-10-21 11:16:14 -07:00
Michael Zhu
f4cb8cfb7e Support arbitrary # of tokens in DeploymentManager 2019-10-21 11:16:14 -07:00
Xianny
ce9f051d42 Create @0x/contracts-tests (#2261)
* Create @0x/contracts-tests

* Move tests from @0x/contracts-dev-utils
2019-10-21 10:23:46 -07:00
Amir Bandeali
083216a0c6 Merge pull request #2271 from 0xProject/feat/3.0/zero-ex-governor
Rename AssetProxyOwner to ZeroExGovernor
2019-10-19 17:05:07 -07:00
Amir Bandeali
820b40e227 Import ZeroExGovernor instead of AssetProxyOwner in testnet migrations 2019-10-18 16:31:38 -07:00
mzhu25
59a38a8db0 Merge pull request #2269 from 0xProject/refactor/balance-stores
BalanceStore++
2019-10-18 09:01:33 -07:00
Lawrence Forman
d0884dcb4d Merge pull request #2267 from 0xProject/feat/3.0/staking/MixinStake-unit-tests
Create MixinStake unit tests
2019-10-18 11:41:18 -04:00
Lawrence Forman
c7ca625408 @0x/contracts-staking: Fix MixinStake unit tests typo. 2019-10-18 10:45:07 -04:00
Lawrence Forman
e46f51339a @0x/contracts-staking: Address review comments. 2019-10-18 10:42:47 -04:00
Michael Zhu
b45ec47eee address comments 2019-10-17 19:53:43 -07:00
Amir Bandeali
c50cbd7a75 Rename AssetProxyOwner to ZeroExGovernor throughout all contracts packages 2019-10-17 17:41:54 -07:00
Amir Bandeali
5ddc35fdf2 Rename AssetProxyOwner to ZeroExGovernor 2019-10-17 17:41:54 -07:00
Amir Bandeali
d6c064b9c3 Merge pull request #2224 from 0xProject/feat/3.0/testnet-migrations
3.0 testnet migrations
2019-10-17 17:38:09 -07:00
Amir Bandeali
caf6329bb3 Merge branch '3.0' into feat/3.0/testnet-migrations 2019-10-17 17:13:12 -07:00
Lawrence Forman
008938cf5b @0x/contracts-staking: Check order of increase and derease balance operations in MixinStake unit tests. 2019-10-17 14:09:46 +10:00
Fabio B
3fd29656cb Merge pull request #2268 from 0xProject/addERC1155MintableSupport
Add erc1155 mintable support
2019-10-17 11:50:02 +08:00
Michael Zhu
ffac52f42e lint 2019-10-16 20:19:04 -07:00
fabioberger
9114510c00 Add enum-naming linter ignore to wrappers to fix linter issue with URL in ERC1155Mintable 2019-10-17 12:16:42 +09:00
fabioberger
2dbda6fc42 Deploy ERC1155Mintable in migration 2019-10-17 12:16:08 +09:00
fabioberger
eae4001622 Update ganache-cli version in migration dockerfile 2019-10-17 12:16:08 +09:00
fabioberger
727d0498b6 Export ERC1155Mintable from abi-gen-wrapper 2019-10-17 12:16:08 +09:00
fabioberger
e43f2d39bf Add ERC1155Mintable to artifacts and abi-gen-wrappers packages 2019-10-17 12:16:08 +09:00
Michael Zhu
cde0169733 Update BlockchainBalanceStore to not rely on erc*_wrappers + better balance equality assertions 2019-10-16 18:46:55 -07:00
Xianny
0e90b0e7d0 Make wrappers small again (#2243)
* introduce --debug option to abi-gen and remove debug functions from @0x/abi-gen-wrappers
* make evmExecAsync protected; ignore deployedBytecode in doc comment
* trim deployedBytecode so it's undefined unless a contract has pure functions
* remove validateAndSendTransactionAsync
* Create `AwaitTransactionSuccessOpts` and `SendTransactionOpts` types 
* Remove duplicate types `IndexedFilterValues`, `DecodedLogEvent`, `EventCallback` from `@0x/base-contract`
2019-10-16 09:38:34 -07:00
Lawrence Forman
b793a31cdd @0x/contracts-staking: Create MixinStake unit tests. 2019-10-16 22:53:36 +10:00
James Towle
23198174f3 Merge pull request #2254 from 0xProject/fix/t14
Add SafeMath to Multisig
2019-10-15 15:40:48 -07:00
Alex Towle
523bc3f951 Updated Changelogs 2019-10-15 15:00:01 -07:00
Alex Towle
41d99e77c7 @0x:contracts-utils Removed SafeMath and the use of the contract throughout contracts/ 2019-10-15 14:31:48 -07:00
Alex Towle
90193c8197 @0x:contracts-multisig Changed SafeMath to LibSafeMath 2019-10-15 14:31:48 -07:00
Alex Towle
6f5c62914e @0x:contracts-multisig Switched to SafeMath in pastTimeLock 2019-10-15 14:31:48 -07:00
James Towle
17faeae47d Merge pull request #2265 from 0xProject/fix/3.0/c18
Fix/3.0/c18
2019-10-15 11:31:46 -07:00
Alex Towle
7283a16710 @0x:contracts-utils Updated changelog 2019-10-14 11:57:02 -07:00
Alex Towle
52c3dc4ad8 @0x:contracts-utils Fixed and improved the LibBytes tests 2019-10-14 11:54:02 -07:00
Alex Towle
1cf8ae5909 @0x:contracts-utils Removed several functions from LibBytes 2019-10-14 11:54:02 -07:00
Amir Bandeali
51282953bd Merge pull request #2263 from 0xProject/fix/3.0-audit/staking/cumulative-rewards-refactor
Staking: Refactor and slightly simplify rewards tracking
2019-10-14 18:28:03 +09:00
Lawrence Forman
a6603d6bd6 @0x/contracts-staking: Fix typo in MixinCumulativeRewards 2019-10-14 15:19:34 +10:00
Lawrence Forman
54a03eacd6 @0x/contracts-staking: Refactor MixinCumulativeRewards and MixinStakingPoolRewards to better encapsulate cumulative rewards.
`@0x/contracts-staking`: Make sure we don't overwrite an existing CR.
`@0x/contracts-staking`: Remove the need to initialize cumulative rewards when creating a pool.
`@0x/contracts-staking`: Just return an empty CR in `_getCumulativeRewardAtEpoch()` if one can't be found.
2019-10-14 12:36:26 +10:00
Amir Bandeali
43fa753a13 Merge pull request #2262 from 0xProject/fix/staking/simplify-finalization
Staking readability improvements
2019-10-14 10:45:55 +09:00
Amir Bandeali
9d9fe882b6 Remove unnecessary payable keywords 2019-10-14 09:58:31 +09:00
Amir Bandeali
4f6958b7b5 Do not import @0x/contracts-extensions to fix build 2019-10-14 09:46:06 +09:00
Amir Bandeali
9a5752fff9 Remove unused param in Pool struct 2019-10-14 09:45:37 +09:00
Amir Bandeali
c21932d149 Remove _creditRewardsToPool and remove return values from finalizePool 2019-10-13 17:31:55 +09:00
Amir Bandeali
ce6c05637f Update cumulative rewards tracking tests 2019-10-13 17:31:55 +09:00
Amir Bandeali
b0699fc238 Always set cumulative rewards when _withdrawAndSyncDelegatorRewards is called 2019-10-13 17:31:55 +09:00
Amir Bandeali
8bf7c4cf48 Remove unnecessary assert 2019-10-13 17:31:55 +09:00
Lawrence Forman
9f6d113fe8 Merge pull request #2255 from 0xProject/fix/3.0-audit/staking/LibFixedMath-arithmetic-overflows
Fix LibFixedMath arithmetic overflows
2019-10-12 07:38:05 +09:00
James Towle
646507c41a Merge pull request #2253 from 0xProject/fix/t8
Ownership Transferred Event
2019-10-10 16:58:08 -07:00
Alex Towle
65f2626544 @0x:contracts-utils Updated the OwnershipTransferred event to be closer to OpenZeppelin's event 2019-10-10 10:58:58 -07:00
Greg Hysz
7155d878b3 Merge pull request #2257 from 0xProject/cleanup/staking/loadSyncedUnsyncedBalance
Remove `loadSyncedBalance` and `loadUnsyncedBalance`
2019-10-10 16:15:17 +09:00
Greg Hysen
361576814c Removed loadSyncedBalance and loadUnsyncedBalance 2019-10-10 15:51:24 +09:00
Amir Bandeali
aa541d0cad Merge pull request #2256 from 0xProject/feat/staking/immutable
Separate immutable contracts, only inherit as needed
2019-10-10 15:19:37 +09:00
Amir Bandeali
7e58385a78 Separate immutable contracts, only inherit as needed 2019-10-10 15:00:35 +09:00
Amir Bandeali
b5545255d0 Merge pull request #2245 from 0xProject/fix/3.0/validate-assetdata
Enforce assetData is padded to 32 bytes
2019-10-10 10:55:22 +09:00
Lawrence Forman
a22ba8647c Update changelogs 2019-10-10 09:41:57 +09:00
Lawrence Forman
22fc0b4337 @0x/contracts-staking: Add another LibFixedMath.add() test. 2019-10-10 09:31:53 +09:00
Lawrence Forman
063d6ff24e @0x/contracts-staking: Add more overflow safeguards to LibFixedMath. 2019-10-10 09:16:01 +09:00
Lawrence Forman
09c0b83fe3 @0x/utils: Consolidated FixedMathRevertErrors 2019-10-10 09:16:01 +09:00
Lawrence Forman
a42f3d189c @0x/contracts-staking: Implement better overflow detection in LibFixedMath. 2019-10-10 09:16:01 +09:00
Alex Towle
7815da7257 @0x:contracts-utils Addressed review feedback 2019-10-09 10:49:38 -07:00
Amir Bandeali
8e2b971f5a Merge pull request #2249 from 0xProject/feat/staking/catastrophic-failure-backstop
Read-only mode backstop
2019-10-09 19:16:10 +09:00
Amir Bandeali
3fd7132a0d Merge pull request #2248 from 0xProject/fix/staking/cleanup-accounting
Simplify staking state
2019-10-09 18:00:06 +09:00
Amir Bandeali
93edb083fa Remove payable fallback from IStakingProxy, fix linting errors 2019-10-09 17:27:37 +09:00
Amir Bandeali
9e41c648dc Add backstop tests 2019-10-09 17:27:37 +09:00
Amir Bandeali
a7ef54dbff Implement ZrxVaultBackstop 2019-10-09 17:27:37 +09:00
Amir Bandeali
414084a7ad Track state of read-only mode in stakingProxy 2019-10-09 17:27:37 +09:00
Amir Bandeali
681e6eab7a Cleanup language used in comments and variable names 2019-10-09 17:15:25 +09:00
Amir Bandeali
701b203c58 Fix tests 2019-10-09 17:15:25 +09:00
Amir Bandeali
cbd0ca4b60 Make currentEpoch uint64 type, change INACTIVE => UNDELEGATED, and make global balances state a mapping from uin8 => StoredBalance 2019-10-09 17:15:25 +09:00
Amir Bandeali
1626566f93 Change getBalanceOfVault => getBalanceOfZrxVault 2019-10-09 17:15:25 +09:00
Amir Bandeali
ac75053f69 Remove unused rich revert 2019-10-09 17:15:25 +09:00
Amir Bandeali
13afc65b54 Do not store global inactive state 2019-10-09 17:15:25 +09:00
Amir Bandeali
aa0a1bb54d Fix tests to no longer utilize active stake 2019-10-09 17:15:25 +09:00
Amir Bandeali
2e36c7ef83 Remove ACTIVE state 2019-10-09 17:15:25 +09:00
Amir Bandeali
43399a9ad9 Refactor tests to use new getters 2019-10-09 17:15:25 +09:00
Amir Bandeali
2ef546210d Update tests to reflect new withdrawal logic 2019-10-09 17:15:25 +09:00
Amir Bandeali
7b379f3933 Simplify withdrawal flow and storage layout 2019-10-09 17:15:25 +09:00
Amir Bandeali
f8ac986a0f Remove unused struct field 2019-10-09 17:14:28 +09:00
Alex Towle
dc0a78434d @0x:contracts-utils Updated files 2019-10-08 19:27:39 -07:00
Alex Towle
d1b0384aef @0x:contracts-utils Added an event for ownership transfers 2019-10-08 19:22:27 -07:00
Greg Hysz
7ac7f45c4a Merge pull request #2250 from 0xProject/cleanup/staking/simplifyMakers
Simplify Makers Interactions with Staking Pools
2019-10-08 11:25:07 +09:00
Greg Hysen
b3c7ccec57 Changed nextPoolId to lastPoolId 2019-10-08 10:43:18 +09:00
Lawrence Forman
93725ecec0 Merge pull request #2233 from 0xProject/feat/erc20-bridge/uniswap
UniswapBridge
2019-10-08 10:31:47 +09:00
Amir Bandeali
3c31ef188a Merge pull request #2246 from 0xProject/fix/3.0/always-validate-signatures
Always validate order signatures
2019-10-08 10:25:28 +09:00
Lawrence Forman
53df2130ea @0x/contracts-asset-proxy: Remove only modifier on uniswap tests. 2019-10-08 09:27:53 +09:00
Amir Bandeali
8b695f9b98 Fix race condition in tests 2019-10-08 09:12:37 +09:00
Amir Bandeali
d914f6fce9 Test for failure with bad signature after partial fill 2019-10-08 09:12:37 +09:00
Amir Bandeali
e2e5152648 Always validate signatures for all types 2019-10-08 09:12:37 +09:00
Lawrence Forman
d3dcf7fb0c Merge pull request #2247 from 0xProject/fix/3.0-audit/staking/shadowed-variable
fix `_computeUnfinalizedDelegatorReward()` shadowed variable and function mutability
2019-10-07 18:50:32 -05:00
Greg Hysen
a0f5a8b64b Simplify Makers Interactions with Staking Pools.
- No longer an upper limit on how many makers can be in a pool.
- No longer a handshake for a maker to join a pool.
- No longer any special powers given to makers.
- Pool Id starts at 1 and increments by 1.
2019-10-08 06:00:24 +09:00
mzhu25
ee508f70bc Merge pull request #2228 from 0xProject/fix/3.0/refundFinalBalanceNoReentry
refundFinalBalanceNoReentry
2019-10-06 13:39:04 -07:00
mzhu25
200b3d450f Merge pull request #2229 from 0xProject/feature/3.0/update-coordinator
Update Coordinator for 3.0
2019-10-06 13:20:00 -07:00
Michael Zhu
52fc7517f9 Remove approval expirations, address other comments 2019-10-06 12:45:48 -07:00
Michael Zhu
cf517b1459 appease static tests 2019-10-06 12:44:58 -07:00
Michael Zhu
c17984b74f Refactor integration tests (CoordinatorTestFactory) 2019-10-06 12:44:58 -07:00
Michael Zhu
589d2212ee Test coordinator protocol fees 2019-10-06 12:44:58 -07:00
Michael Zhu
9b922f746b Update coordinator tests 2019-10-06 12:44:58 -07:00
Michael Zhu
0e7387550c Update contracts 2019-10-06 12:44:58 -07:00
Lawrence Forman
dbf22583b5 @0x/contracts-asset-proxy: Remove unecessary token allowance when coming from WETH. 2019-10-05 22:37:51 -05:00
Lawrence Forman
6825eb442b @0x/contracts-staking: Fix shadowed variable in MixinStakingPoolRewards._computeUnfinalizedDelegatorReward() and make the function pure. 2019-10-05 17:22:46 -05:00
James Towle
45f284973a Merge pull request #2240 from 0xProject/feature/integration-tests/deployment-manager
Deployment Manager
2019-10-05 15:14:12 -07:00
Lawrence Forman
ef6e691646 @0x/contracts-exchange-libs: Update generated source files after revase. 2019-10-05 16:29:06 -05:00
Lawrence Forman
e67888d65f @0x/contracs-asset-proxy: Pass in minimum buy amounts in the UniswapBridge.
`@0x/contracs-asset-proxy`: Slight refactors in `UniswapBridge`.
2019-10-05 16:27:24 -05:00
Lawrence Forman
584f8b13fe @0x/contracts-asset-proxy: Rebase and update Eth2DaiBridge to use IWallet from exchange-libs. 2019-10-05 13:57:51 -05:00
Lawrence Forman
f993b6d1ed @0x/contracts-exchange: Revert changes to IWallet. 2019-10-05 13:57:51 -05:00
Lawrence Forman
035dc607db @0x/contracts-asset-proxy: Use IWallet from exchange-libs.
`@0x/contracts-asset-proxy`: Fix some comment typos in `UniswapBridge`.
`@0x/contracts-asset-proxy`: Add more allowance tests to the `UniswapBridge` tests.
2019-10-05 13:57:51 -05:00
Lawrence Forman
cf2053ec77 @0x/contracts-exchange-libs: Move IWallet from asset-proxy and exchange packages into this package. 2019-10-05 13:57:51 -05:00
Lawrence Forman
3840ebf538 @0x/contracts-exchange: Move IWallet.sol to exchange-libs. 2019-10-05 13:57:51 -05:00
Lawrence Forman
80cb6b654b @0x/contracts-asset-proxy: Fix linter errors. 2019-10-05 13:57:51 -05:00
Lawrence Forman
ab70c4df74 @0x/contracts-asset-proxy: Remove only modifier on tests. 2019-10-05 13:57:51 -05:00
Lawrence Forman
95e461072f @0x/contracts-asset-proxy: Always set allowance. 2019-10-05 13:57:50 -05:00
Lawrence Forman
2593f1ff30 @0x/contracts-asset-proxy: Update CHANGELOG. 2019-10-05 13:57:50 -05:00
Lawrence Forman
c2261a6bbe @0x/contracts-asset-proxy: Finish off UniswapBridge tests. 2019-10-05 13:57:50 -05:00
Lawrence Forman
b383781870 @0x/contracts-asset-proxy: Getting around stack issues. 2019-10-05 13:57:50 -05:00
Lawrence Forman
7d121bafd0 @0x/contracts-asset-proxy: More work on UniswapBridge tests. 2019-10-05 13:57:50 -05:00
Lawrence Forman
6a2911d10f @0x/contracts-asset-proxy: Start work on UniswapBridge tests. 2019-10-05 13:57:50 -05:00
Lawrence Forman
17362bcf44 @0x/contracts-asset-proxy: Create UniswapBridge. 2019-10-05 13:57:50 -05:00
Amir Bandeali
87906a3af1 Add test for improperly padded assetData 2019-10-04 18:05:20 -07:00
Amir Bandeali
c0c27ed637 Enforce that assetData is padded to 32 bytes, excluding the id, before dispatching transfer 2019-10-04 18:04:44 -07:00
Amir Bandeali
6be5552944 fix static tests 2019-10-04 17:17:07 -07:00
Alex Towle
b4ae42cc9a @0x/contracts-integrations Added the integrations package to the top-level configuration 2019-10-04 16:32:39 -07:00
Alex Towle
3c6957095d @0x:contracts-integrations Addressed review feedback 2019-10-04 15:42:36 -07:00
fabioberger
2020d87824 Fix dist tag issue in publish script 2019-10-04 20:44:18 +08:00
Amir Bandeali
ac1063dd68 Merge branch '3.0' into feat/3.0/testnet-migrations 2019-10-03 23:04:07 -07:00
fabioberger
b8e01d7be5 Add beta version to next tslint-config release 2019-10-04 13:28:25 +08:00
Alex Towle
24e4567b25 @0x:contracts-integration-tests Added an integration-tests package and a deployment manager class 2019-10-03 19:41:51 -07:00
Jacob Evans
ccf40fd65e Merge pull request #2242 from 0xProject/fix-mesh-orderbook-types
HACK: Types as any until Mesh RPC client is published
2019-10-03 18:21:24 -07:00
Jacob Evans
d4729e2669 Increase HEAP space for Instant 2019-10-03 17:47:33 -07:00
Jacob Evans
52d38c63de HACK the types until Mesh RPC client is published 2019-10-03 16:40:42 -07:00
Jacob Evans
086c30831d Merge pull request #2241 from 0xProject/rm-dev-tools-pages
Remove dev tools pages
2019-10-03 16:31:44 -07:00
Jacob Evans
4be83de7e5 Remove dev tools pages 2019-10-03 16:25:46 -07:00
Jacob Evans
c60d1e50c5 Publish
- @0x/contracts-asset-proxy@2.3.0-beta.0
 - @0x/contracts-coordinator@2.1.0-beta.0
 - @0x/contracts-dev-utils@0.1.0-beta.0
 - @0x/contracts-erc1155@1.2.0-beta.0
 - @0x/contracts-erc20@2.3.0-beta.0
 - @0x/contracts-erc721@2.2.0-beta.0
 - @0x/contracts-exchange-forwarder@3.1.0-beta.0
 - @0x/contracts-exchange-libs@3.1.0-beta.0
 - @0x/contracts-exchange@2.2.0-beta.0
 - @0x/contracts-extensions@4.1.0-beta.0
 - @0x/contracts-multisig@3.2.0-beta.0
 - @0x/contracts-staking@1.1.0-beta.0
 - @0x/contracts-test-utils@3.2.0-beta.0
 - @0x/contracts-utils@3.3.0-beta.0
 - 0x.js@7.1.0-beta.0
 - @0x/abi-gen-wrappers@5.4.0-beta.0
 - @0x/abi-gen@4.3.0-beta.0
 - @0x/assert@2.2.0-beta.0
 - @0x/asset-buyer@6.2.0-beta.0
 - @0x/asset-swapper@2.1.0-beta.0
 - @0x/base-contract@5.5.0-beta.0
 - @0x/connect@5.1.0-beta.0
 - @0x/contract-addresses@3.3.0-beta.0
 - @0x/contract-artifacts@2.3.0-beta.0
 - @0x/contract-wrappers@12.2.0-beta.0
 - @0x/contracts-gen@1.1.0-beta.0
 - @0x/dev-utils@2.4.0-beta.0
 - ethereum-types@2.2.0-beta.0
 - @0x/instant@1.0.32
 - @0x/json-schemas@4.1.0-beta.0
 - @0x/migrations@4.4.0-beta.0
 - @0x/monorepo-scripts@1.0.38
 - @0x/order-utils@8.5.0-beta.0
 - @0x/orderbook@0.1.0-beta.0
 - @0x/sol-compiler@3.2.0-beta.0
 - @0x/sol-coverage@3.1.0-beta.0
 - @0x/sol-doc@2.1.0-beta.0
 - @0x/sol-profiler@3.2.0-beta.0
 - @0x/sol-resolver@2.1.0-beta.0
 - @0x/sol-trace@2.1.0-beta.0
 - @0x/sol-tracing-utils@6.1.0-beta.0
 - @0x/sra-spec@2.1.0-beta.0
 - @0x/subproviders@5.1.0-beta.0
 - @0x/testnet-faucets@1.0.88
 - @0x/types@2.5.0-beta.0
 - @0x/typescript-typings@4.4.0-beta.0
 - @0x/utils@4.6.0-beta.0
 - @0x/web3-wrapper@6.1.0-beta.0
2019-10-03 14:10:22 -07:00
Jacob Evans
501f5ad3de Updated CHANGELOGS & MD docs 2019-10-03 14:10:00 -07:00
Fabio B
9fe6c196ad Merge pull request #2237 from 0xProject/fix/reenablePublishAndDocGenCITests
Re-enable publish-test and doc-gen-test on CI
2019-10-04 01:58:36 +08:00
fabioberger
6d462b0598 Fix prettier 2019-10-03 15:28:06 +08:00
fabioberger
3832c66ad0 Exclude unready packages from install step as well 2019-10-03 15:08:05 +08:00
fabioberger
57028069c0 Don't run test-publish for contract-coordinator and contracts-extensions since they're not ready yet 2019-10-03 14:32:55 +08:00
fabioberger
8d84ac9cf8 increase maxBuffer on exec call 2019-10-03 14:07:06 +08:00
fabioberger
17219d22c3 Add mocha types to deps 2019-10-03 13:10:04 +08:00
fabioberger
bf4005b0ee Move mocha to a dependency since it's is actually a dep not a devDep in this case 2019-10-03 11:58:17 +08:00
fabioberger
d8605ed91d Remove ambient Mocha declaration 2019-10-03 11:42:19 +08:00
fabioberger
f18e2a09e6 Change publish script so that we don't generate MD docs unless it's an actual publish 2019-10-03 10:59:31 +08:00
fabioberger
d5c0f5aa47 Move chai extension types out of @0x/typescript-typings 2019-10-03 10:37:09 +08:00
fabioberger
2825a201cd Add missing exports to 0x.js 2019-10-02 21:35:47 +08:00
fabioberger
2d69afec86 Increase timeout on publish test 2019-10-02 21:32:18 +08:00
fabioberger
851e4bfbea Fix prettier 2019-10-02 20:57:57 +08:00
fabioberger
c63745c2ce Fix deps 2019-10-02 20:57:52 +08:00
fabioberger
95f11f2d0e Fix changelog version for staking package 2019-10-02 20:52:25 +08:00
fabioberger
30417fbf24 Increase doc gen timeout 2019-10-02 20:51:41 +08:00
fabioberger
06f095ca23 Move types part of pkg exported interfaces to @0x/types from base-contract so more easily accessible 2019-10-02 19:06:54 +08:00
fabioberger
30141ca6cf Fix md gen for contract-wrappers so also includes re-exported dep content 2019-10-02 18:42:41 +08:00
fabioberger
c4b69efdd1 Update package index.ts exports so that we are able to generate docs 2019-10-02 18:16:10 +08:00
fabioberger
d810aff337 Add latest solc version paths 2019-10-02 17:14:07 +08:00
fabioberger
83532fdae7 Fix Solc bin path so it's _outside_ lib dir and persists across rebuilds 2019-10-02 17:13:54 +08:00
fabioberger
043534dd56 Add back publish and doc gen tests to CI 2019-10-02 14:29:13 +08:00
fabioberger
a90c808fb4 Remove Geth testing from CI 2019-10-02 14:28:27 +08:00
Fabio B
a06c39df9f Merge pull request #2231 from 0xProject/fix/remove-fill-scenarios
Remove fill-scenarios package
2019-10-02 08:23:03 +02:00
xianny
24c3aefb6f remove fill-scenarios 2019-10-02 14:03:50 +08:00
Jacob Evans
9544d317a0 Merge pull request #2234 from 0xProject/v3-rc0-packages
V3 rc0 packages
2019-10-01 22:42:08 -07:00
Amir Bandeali
650efb95e2 Add more contract configs tests 2019-10-01 22:18:09 -07:00
Jacob Evans
506d27816e Update Ropsten devUtils and Forwarder 2019-10-01 22:14:01 -07:00
Jacob Evans
f5a0c87fdc Update Exchange, Forwarder, DevUtils 2019-10-01 22:14:01 -07:00
Jacob Evans
90541f0436 Updated Forwarder 2019-10-01 22:14:01 -07:00
Amir Bandeali
76cac53692 Merge pull request #2235 from 0xProject/fix/3.0/deployment-tests
Fix deployment and configuration tests
2019-10-01 22:08:25 -07:00
Fabio B
18366bd58d Merge pull request #2232 from 0xProject/refactor/3.0-wrappers
Reduce exports from 0x.js
2019-10-02 06:45:02 +02:00
Amir Bandeali
27c039d51c Fix deployment and configuration tests 2019-10-01 21:44:43 -07:00
Fabio B
8465be2a03 Merge pull request #2226 from 0xProject/feature/publishPrep
Final RC publish prep
2019-10-02 05:02:53 +02:00
Amir Bandeali
7d6f49172d Merge pull request #2223 from 0xProject/feat/3.0/do-not-authorize-owner
Do not authorize owner by default
2019-10-01 19:54:46 -07:00
Lawrence Forman
d15f4de4ae @0x/contracts-asset-proxy: Inline _grantAllowances() in Eth2DaiBridge. 2019-10-01 19:46:14 -07:00
Lawrence Forman
4098238019 @0x/contracts-asset-proxy: Set allowance every time. 2019-10-01 19:46:14 -07:00
Lawrence Forman
1356237ec9 @0x/contracts-asset-proxy: Rebase and use IERC20Bridge 2019-10-01 19:46:14 -07:00
Lawrence Forman
35daecd5ae @0x/contracts-asset-proxy: Rebase and use @0x/types.AssetProxyId. 2019-10-01 19:46:14 -07:00
Lawrence Forman
bb87c8e7b5 @0x/contracts-asset-proxy: Switch Eth2DaiBridge to support arbitrary tokens.
`@0x/contracts-asset-proxy`: Support non-conformant tokens in Eth2DaiBridge
2019-10-01 19:46:14 -07:00
Lawrence Forman
48f7a24505 @0x/contracts-asset-proxy: Rebase and update tests for new proxy selector. 2019-10-01 19:46:14 -07:00
Lawrence Forman
98c59091ab @0x/contracts-asset-proxy: Add comments and update naming convention in IEth2Dai. 2019-10-01 19:46:14 -07:00
Lawrence Forman
4ca08adcfa @0x/contracts-asset-proxy: Rebase and add extra comments. 2019-10-01 19:46:14 -07:00
Lawrence Forman
29bcc1b5b7 @0x/contracts-asset-proxy: omg these insidious only modifiers. 2019-10-01 19:46:14 -07:00
Lawrence Forman
6e4186adbe @0x/contracts-asset-proxy: Add some more unit tests for Eth2DaiBridge. 2019-10-01 19:46:14 -07:00
Lawrence Forman
38e540ad9f @0x/contracts-asset-proxy: Remove only modifier on tests. 2019-10-01 19:46:14 -07:00
Lawrence Forman
7762b7b665 @0x/contracts-asset-proxy: Add signature validation. 2019-10-01 19:46:14 -07:00
Lawrence Forman
82ac8e29e3 @0x/contracts-asset-proxy: Add Eth2DaiBridge and tests. 2019-10-01 19:46:14 -07:00
fabioberger
e074335285 Null out all contracts not re-deployed or updated to V3 2019-10-02 09:15:50 +08:00
xianny
3adbe843da update contract-addresses version 2019-10-01 17:51:25 -07:00
mzhu25
d5c8c076dc Merge pull request #2216 from 0xProject/feature/3.0/forwarder-protocol-fees
Forwarder protocol fees
2019-10-01 17:45:02 -07:00
xianny
1d68c4105a redo changes from #2147 2019-10-01 17:17:40 -07:00
Michael Zhu
8077123e9f update contracts and tests to support different maker assets 2019-10-01 16:19:47 -07:00
Michael Zhu
3948f8b66b Replace nonReentrant + refundFinalBalance with refundFinalBalanceNoReentry 2019-10-01 15:39:50 -07:00
Michael Zhu
0ff8b12770 rmeove maker asset equality check; update to reflect removal of weth asset proxy 2019-10-01 13:08:17 -07:00
fabioberger
39a8c0f4e6 Update the Ganache snapshot addresses with latest v3 snapshot 2019-10-01 18:43:56 +08:00
fabioberger
8c5e12d389 Update or add CHANGELOG entries for all packages that will be published by Lerna to include a beta version. This dictates the version published to NPM and avoids any default patch bumps 2019-10-01 17:56:57 +08:00
fabioberger
71660850af Add new addresses to contract-addresses given the latest deployment 2019-10-01 17:11:54 +08:00
fabioberger
b83043648e Also exclude coordinator and extension contract packages when running build 2019-10-01 16:58:05 +08:00
Michael Zhu
b01de802cb address styling nits; only calculate protocol fee once 2019-09-30 21:51:34 -07:00
Michael Zhu
e954e9ca20 update tests 2019-09-30 21:51:34 -07:00
Michael Zhu
3f8639bd9c Update MixinExchangeWrapper to handle protocol fees 2019-09-30 21:51:34 -07:00
Amir Bandeali
ffcd297e5b Rename old exchange address to exchangeV2 2019-09-30 21:03:27 -07:00
Fabio B
56c956df44 Merge pull request #2225 from 0xProject/feature/addDistTagToPublish
Feature/add dist tag to publish
2019-10-01 05:41:19 +02:00
James Towle
c4b621e44d Merge pull request #2215 from 0xProject/feature/staking/end-to-end/deployment-test
End-to-end Deployment Test
2019-09-30 19:42:41 -07:00
Amir Bandeali
cfb099c65c Fix linting errors 2019-09-30 19:00:17 -07:00
Amir Bandeali
ba5c702a9e Update CHANGELOGs 2019-09-30 19:00:17 -07:00
Amir Bandeali
9d4010299a Cleanup migration scripts 2019-09-30 19:00:17 -07:00
Amir Bandeali
b5492bb023 Add ZrxVault testnet addresses to deployment constants 2019-09-30 19:00:17 -07:00
Amir Bandeali
76724a6c73 Implement initial 3.0 migrations script 2019-09-30 19:00:17 -07:00
Amir Bandeali
57ec0858fe Fix migrations build 2019-09-30 19:00:17 -07:00
Amir Bandeali
b281b9aac8 Update 3.0 testnet addresses 2019-09-30 19:00:17 -07:00
Amir Bandeali
f4453c0966 Regenerate abi-gen-wrappers 2019-09-30 18:57:17 -07:00
Amir Bandeali
ebd328db06 Add getSelector helper function to Typescript templates 2019-09-30 18:57:17 -07:00
fabioberger
9a658bf932 Change tag to protocolV3 to disambiguate with a specific version of a package 2019-10-01 09:04:20 +08:00
Francesco Agosti
d6d506d1c5 Merge pull request #2219 from 0xProject/feature/sra-v3
Upgrade @0x/json-schemas, @0x/types, @0x/connect, @sra-spec to SRA V3
2019-09-30 18:00:29 -07:00
Lawrence Forman
2c8f7fac0e Merge pull request #2220 from 0xProject/feat/erc20-bridge/hello-world
ERC20BridgeProxy
2019-09-30 20:52:36 -04:00
Alex Towle
072ff65bf9 @0x:contracts-staking Removed multisig as a dependency 2019-09-30 17:46:57 -07:00
Amir Bandeali
aa198ad15f Add tests for adding/removing an exchange called by owner 2019-09-30 17:42:25 -07:00
Amir Bandeali
745da8e363 Fix tests 2019-09-30 17:36:37 -07:00
Amir Bandeali
be173a9970 Add sender as authorized address before calling init in test contracts 2019-09-30 17:36:37 -07:00
Amir Bandeali
8b2b500414 Remove authorization of owner in StakingProxy after init is called in constructor 2019-09-30 17:36:37 -07:00
Amir Bandeali
98d1f5405a Do not authorize owner in ZrxVault constructor 2019-09-30 17:36:37 -07:00
fragosti
03595dd1dd Run prettier 2019-09-30 17:28:41 -07:00
Lawrence Forman
6da48be1a4 @0x/contracts-asset-proxy: Merge ERC20Bridge into IERC20Bridge. 2019-09-30 17:28:36 -07:00
fragosti
9b91d574f8 Fix failing json-schema test 2019-09-30 17:27:01 -07:00
Alex Towle
6ca8edbf19 @0x:contracts-exchange Moved the deployment test to the exchange and addressed other review comments 2019-09-30 17:25:31 -07:00
Lawrence Forman
579dba1473 @0x/contracts-asset-proxy: Minor ERC20BridgeProxy test changes. 2019-09-30 17:06:31 -07:00
Amir Bandeali
1b5fa15c8c Merge pull request #2222 from 0xProject/feat/3.0/remove-weth-asset-proxy
Remove wethAssetProxy and wethAssetData from staking contracts
2019-09-30 17:03:16 -07:00
Lawrence Forman
737ad586a5 @0x/types: Add ERC20Bridge to AssetProxyId 2019-09-30 16:12:01 -07:00
F. Eugene Aumson
c051e11a49 OrderValidationUtils: don't parse fee asset data when there are no fees specified (#2218)
* exhibit bug: empty fee asset data induces revert

* fix bug: don't parse fee asset data unless fee>0

* Update DevUtils Kovan contract address
2019-09-30 17:53:21 -04:00
Amir Bandeali
a5692690dc Fix protocol fees tests 2019-09-30 09:37:57 -07:00
Amir Bandeali
98106ca8a2 Fix test conttracts 2019-09-30 09:37:53 -07:00
fabioberger
891d685951 Pass '3.0' tag when publishing so that publishes from 3.0 branch don't clobber the 2.1 packages installed with the default 'latest' tag 2019-09-30 22:17:44 +08:00
fabioberger
991cbc9f4e Add ability to pass specific dist tag to npm publish command from publishing flow 2019-09-30 22:16:56 +08:00
Lawrence Forman
8006e4fe3b @0x/contracts-asset-proxy: Change proxy ID and add proxy signature to IAssetData. 2019-09-29 21:53:42 -04:00
Amir Bandeali
f17c6b0a83 Remove unused IAssetProxy imports 2019-09-29 15:45:27 -07:00
Amir Bandeali
57ca601be1 Remove wethAssetProxy and wethAssetData from staking contract 2019-09-29 15:45:08 -07:00
Lawrence Forman
b50e26dc2a @0x/contracts-asset-proxy: Rename IERC20Bridge.transfer() -> IERC20Bridge.withdrawTo().
`@0x/contracts-asset-proxy`: Make `bridgeData` last parameter in `IERC20Bridge.withdrawTo()`.
`@0x/contracts-asset-proxy`: Reuse `PROXY_ID` as `BRIDGE_SUCCESS`.
2019-09-29 17:10:38 -04:00
Lawrence Forman
b728d13d8c @0x/contracts-asset-proxy: Remove only tests modifier. 2019-09-27 23:54:32 -04:00
Lawrence Forman
1959d149f8 @0x/contracts-asset-proxy: Fix incorrect comments in ERC20BridgeProxy tests. 2019-09-27 19:49:23 -04:00
Lawrence Forman
3e2e05caf2 Update changelogs 2019-09-27 19:47:14 -04:00
Lawrence Forman
d6a4d67a14 @0x/contracts-asset-proxy: Add ERC20BridgeProxy and tests. 2019-09-27 19:33:33 -04:00
Lawrence Forman
cf8d424b9b @0x/contracts-test-utils: Add number_utils.ts and hexSize(). 2019-09-27 19:32:55 -04:00
Lawrence Forman
a9f1237208 ethereum-types: Add DecodedLogs type (again?). 2019-09-27 19:32:05 -04:00
fragosti
319b4dfd75 Remove unused imports 2019-09-27 16:00:41 -07:00
fragosti
d39fcd3475 Upgrade sra-spec 2019-09-27 15:49:57 -07:00
fragosti
c7b7f57ab2 Update request types 2019-09-27 15:25:43 -07:00
fragosti
a36a5366d3 Update connect tests 2019-09-27 15:25:18 -07:00
fragosti
87615025fe Remove Client type 2019-09-27 15:00:35 -07:00
fragosti
5b0fc813c4 Update json-schemas 2019-09-27 15:00:24 -07:00
Francesco Agosti
d21f978def Merge pull request #2212 from 0xProject/refactor/no-domain-in-order
Remove domain from Order and remove OrderWithoutDomain type
2019-09-27 14:04:18 -07:00
fragosti
a9ecf7f1f3 Fix order schema typo 2019-09-27 13:30:30 -07:00
mzhu25
f5ad65bb8a Merge pull request #2217 from 0xProject/feature/contracts-staking/mixin-stake-storage-unit-tests
MixinStakeStorage unit tests
2019-09-27 13:20:42 -07:00
fragosti
88dcf6350d Fix exchange-libs test 2019-09-27 13:20:09 -07:00
Michael Zhu
6cfc17de35 MixinStakeStorage unit tests 2019-09-27 13:01:20 -07:00
fragosti
a2d105593e Add to orderTypedData comment 2019-09-27 12:49:01 -07:00
fragosti
efd5eff22c Fix tests 2019-09-27 12:46:20 -07:00
Alex Towle
9282684d93 @0x:contracts-staking Added a full end-to-end test of a deployment of the exchange and staking system 2019-09-26 18:10:52 -07:00
James Towle
c9e03f7d42 Merge pull request #2211 from 0xProject/feature/staking/exchange-manager-units
`@0x:contracts-staking` Added unit tests for MixinExchangeManager
2019-09-26 15:53:40 -07:00
Xianny
690b31c9be update artifacts and wrappers with pre-audit contracts (#2213)
* update artifacts and wrappers with pre-audit contracts

* increase bundlesize
2019-09-26 09:35:24 -07:00
Xianny
cb20f03a92 Use hardcoded deployedBytecode for local EVM execution (#2198)
* hardcode deployedBytecode in contracts

* log warning if bytecode is empty or invalid

* be typesafe
2019-09-26 08:38:29 -07:00
David Sun
97eabc6c03 Merge pull request #2157 from 0xProject/feature/orderbook-removing-smart-routing-logic
Refactored asset-swapper smart logic and renamed options
2019-09-26 09:18:05 -04:00
fragosti
f0e0f08e0c Run linter and prettier 2019-09-25 18:44:19 -07:00
fragosti
470643ee07 Fix tests 2019-09-25 18:44:19 -07:00
fragosti
8ba38b9b29 Remove the OrderWithoutDomain type 2019-09-25 18:44:19 -07:00
fragosti
9870f55d24 Remove domain from Order type 2019-09-25 18:44:19 -07:00
Xianny
23b724dde4 Merge pull request #2209 from 0xProject/fix/all-tests
Enable tests on 3.0
2019-09-25 18:32:43 -07:00
Alex Towle
3fa922dbab @0x:contracts-staking Wrote a basic deployment test 2019-09-25 18:09:50 -07:00
Alex Towle
aa7f082d56 @0x:contracts-staking Addressed review comments 2019-09-25 16:48:34 -07:00
Alex Towle
b178d025b5 @0x:contracts-staking Added unit tests for MixinExchangeManager 2019-09-25 15:32:02 -07:00
David Sun
e333ab18c7 removed smart quote consumer in favor of utils 2019-09-25 18:30:21 -04:00
David Sun
b60db6ac72 removed smart logic and renamed options 2019-09-25 18:30:21 -04:00
Lawrence Forman
96c8da9fdd Merge pull request #2207 from 0xProject/fix/3.0/improve-readability
Improve readability, fix `_trySetCumulativeReward` logic
2019-09-25 17:14:06 -04:00
Greg Hysz
fca883a4aa Merge pull request #2208 from 0xProject/cleanup/staking/spec
Updated README to point to new specification
2019-09-25 14:01:51 -07:00
David Sun
e60d43110d Merge pull request #2159 from 0xProject/feature/asset-swapper-smarter-fee-logic
Feature asset-swapper smarter fee logic
2019-09-25 16:45:41 -04:00
Greg Hysen
b9b135cfa2 Finished removing outdated contract comments 2019-09-25 13:41:27 -07:00
Lawrence Forman
f925c35344 @0x/contracts-staking: Always do _withdrawAndSyncDelegatorRewards() before staking operations and always add a CR (if unset) in _withdrawSyncDelegatorRewards()`. 2019-09-25 16:34:06 -04:00
Greg Hysen
ca2e9bed27 Updated README to point to new specification, plus removed images we no longer need. 2019-09-25 12:48:12 -07:00
Lawrence Forman
5b77e2c8ac @0x/contracts-staking: Fix stake accounting. 2019-09-25 15:29:22 -04:00
Amir Bandeali
9e3331d018 Fix ordering of function calls, remove optimization in _forceSetCumulativeReward 2019-09-25 11:31:30 -07:00
Amir Bandeali
4440075425 Inline _forceSetMostRecentCumulativeRewardEpoch 2019-09-25 11:03:26 -07:00
xianny
626948774b add comment 2019-09-25 11:01:30 -07:00
Amir Bandeali
25cb1c1138 Remove epoch param that is always equivalent to currentEpoch 2019-09-25 10:58:16 -07:00
xianny
4a173deb27 Merge branch '3.0' into fix/all-tests 2019-09-25 10:51:22 -07:00
xianny
245c87f026 re-enable test-rest 2019-09-25 10:48:55 -07:00
Amir Bandeali
22a6de48ae Remove arguments that are unnecessarily passed around 2019-09-25 10:43:14 -07:00
Xianny
a347c1e848 Remove unnecessary function binding (#2202)
* remove unnecessary function binding

* reenable tests
2019-09-25 09:49:47 -07:00
mzhu25
e4ab832ced Merge pull request #2205 from 0xProject/feature/contracts-staking/rip-mixin-vault-core
Consolidate MixinVaultCore and ZrxVault + unit tests
2019-09-24 23:23:32 -07:00
Amir Bandeali
d07005dcbe Change increment -> increase and decrement -> decrease 2019-09-24 23:04:37 -07:00
Michael Zhu
dc06497cae consolidate MixinVaultCore and ZrxVault 2019-09-24 23:04:17 -07:00
Amir Bandeali
c1871b5bca Fix xumulative reward tests 2019-09-24 23:01:44 -07:00
Amir Bandeali
410b9c50d3 Flatten _withdrawAndSyncDelegatorRewards function, fix bug where cumulative rewards are always reset 2019-09-24 23:01:31 -07:00
James Towle
1c42d0ab3c Merge pull request #2206 from 0xProject/fix/3.0/cleanup-inheritance-again
Cleanup inheritance... again
2019-09-24 19:13:54 -07:00
Amir Bandeali
98698f702f Remove redundant inheritance and imports 2019-09-24 18:47:27 -07:00
Amir Bandeali
4784131dca Merge pull request #2203 from 0xProject/feat/3.0/consolidate-rich-reverts
Cleanup rich reverts
2019-09-24 18:32:41 -07:00
James Towle
6eb28b792a Merge pull request #2204 from 0xProject/feature/staking/move-storage-layout-assertions
Feature/staking/move storage layout assertions
2019-09-24 18:32:12 -07:00
Amir Bandeali
57f5b12e24 Cleanup rich reverts 2019-09-24 18:13:37 -07:00
Amir Bandeali
e5aaf68277 Use uin8 instead of uint256 for status 2019-09-24 18:13:37 -07:00
Alex Towle
b62486923f @0x:contracts-staking Removed storage assertions from Staking and moved them to a test contract 2019-09-24 18:12:00 -07:00
Amir Bandeali
322a0a5967 Merge pull request #2201 from 0xProject/fix/3.0/rename-owner
Rename shadowed instances of `owner` to `staker`
2019-09-24 17:46:38 -07:00
Amir Bandeali
f30c2c4a23 Make setZrxProxy callable by authorized address rather than only owner 2019-09-24 17:27:53 -07:00
xianny
44e5fa5b25 improve readability of async error tests 2019-09-24 16:53:59 -07:00
Amir Bandeali
18a86ef234 Replace all shadowed instances of 'owner' with 'staker' 2019-09-24 16:52:09 -07:00
Alex Towle
a6af3744e2 @0x:contracts-staking Improved the test coverage of MixinStakingPool 2019-09-24 16:49:34 -07:00
Amir Bandeali
9b40164787 Merge pull request #2195 from 0xProject/feat/3.0/deployment-constants
Make wethAssetProxy and zrxVault deployment constants
2019-09-24 16:46:21 -07:00
xianny
52e8cf1366 really fix async error tests 2019-09-24 16:45:24 -07:00
Amir Bandeali
1b159f5ccc Make deployment constant getters public 2019-09-24 16:43:08 -07:00
xianny
893ae35296 exclude lib files from tsc build 2019-09-24 16:24:44 -07:00
Amir Bandeali
85e56706bf Remove wethAssetProxy and zrxVault from storage layout assertions 2019-09-24 16:19:53 -07:00
Amir Bandeali
b8b21cefe3 Make deployment constants private and use string reverts for constructor assertions 2019-09-24 16:19:53 -07:00
Amir Bandeali
6d7bf12ade Make wethAssetProxy and zrxVault deployment constants 2019-09-24 16:19:53 -07:00
Xianny
5266816dd6 Quick fix to abi-gen test (#2197) 2019-09-24 16:11:17 -07:00
Amir Bandeali
0c5f0271c7 Merge pull request #2190 from 0xProject/feat/3.0/consolidate-pool-mixins
Consolidate staking pool mixins
2019-09-24 14:00:28 -07:00
Greg Hysz
b65fd06e95 Merge pull request #2188 from 0xProject/feature/staking/remove-ref-counting
Remove reference counting for cumulative rewards
2019-09-24 14:00:17 -07:00
Amir Bandeali
7f51822bfc Fix storage layout assertions 2019-09-24 13:38:48 -07:00
Amir Bandeali
1acd8d9577 Make _poolJoinedByMakerAddress internal 2019-09-24 13:36:54 -07:00
Amir Bandeali
8aa302f6fc Update OnlyCallableByPoolOperatorOrMakerError params and address PR feedback 2019-09-24 13:36:54 -07:00
Amir Bandeali
f8af5879af Remove _getStakingPoolOperator internal getter function 2019-09-24 13:36:54 -07:00
Amir Bandeali
a7aa7feff4 Remove getAvailableRewardsBalance public function, make wethReservedForPoolRewards public 2019-09-24 13:36:54 -07:00
Amir Bandeali
b6a96cea23 Address PR comments 2019-09-24 13:36:54 -07:00
Amir Bandeali
50b02a4a55 Add more pool tests 2019-09-24 13:36:54 -07:00
Amir Bandeali
8a2b178e6f Remove isMakerAssignedToStakingPool to reduce sloads 2019-09-24 13:36:54 -07:00
Amir Bandeali
7f1afb57b0 Consolidate MixinStakingPool, MixinStakingPoolMakers, and MixinStakingPoolModifiers 2019-09-24 13:36:54 -07:00
Amir Bandeali
0bc4b50818 Add codesize tests 2019-09-24 13:36:54 -07:00
Greg Hysen
91de2194eb Removed reference counting from storage layout test 2019-09-24 13:35:41 -07:00
Greg Hysen
fef06908ec Removed instances fo a frivilous currentEpoch parameter 2019-09-24 13:32:20 -07:00
Greg Hysen
a012eb0cae Updated changelog and ran prettier 2019-09-24 13:32:20 -07:00
Greg Hysen
08c805a489 Removed explicit dependency for delegator on the next epoch after staking. 2019-09-24 13:32:20 -07:00
Greg Hysen
5b595dd080 Remove reference counting for cumulative rewards 2019-09-24 13:32:20 -07:00
James Towle
c29a22187c Merge pull request #2199 from 0xProject/feature/staking/storage-layout-assertion
Feature/staking/storage layout assertion
2019-09-24 13:30:56 -07:00
Jacob Evans
44f6d21e9b Merge pull request #2196 from 0xProject/quick-fixes
Quick fixes
2019-09-24 21:48:58 +02:00
Alex Towle
ef04248191 @0x:contracts-staking Addressed review comments 2019-09-24 10:58:51 -07:00
Jacob Evans
1b47c473b4 Quick fixes
* Fixed the webpack publish for asset swapper to be in line with 0x.js
* Modified the migration snapshot name to not clobber v2 until we're
ready to overwrite
* Added filler transactions to keep contract addresses stable whilst
  asset proxy is disabled
* Non-private package publish for orderbook
2019-09-24 15:48:35 +02:00
Amir Bandeali
fe1fea9a2d Merge pull request #2172 from 0xProject/fix/3.0/exchange/eip712domain
Fix eip712 domain
2019-09-23 21:07:59 -07:00
Alex Towle
970f77beb0 @0x:contracts-staking Added storage layout assertions to the staking contract 2019-09-23 18:26:51 -07:00
Amir Bandeali
2587cd380f Merge pull request #2186 from 0xProject/feat/3.0/delete-vaults
Delete `StakingPoolRewardVault` and `EthVault`
2019-09-23 18:05:53 -07:00
Amir Bandeali
04eab19f15 Fix lingering cases of verifyingContractAddress 2019-09-23 17:56:42 -07:00
Amir Bandeali
abb2b46ed3 Remove vaults from variable names and comments 2019-09-23 17:37:04 -07:00
Alex Towle
db241e8f90 @0x:contracts-staking Modified Staking events to improve their usability 2019-09-23 17:32:52 -07:00
Amir Bandeali
5bbd57d236 Delete unused rich reverts 2019-09-23 17:28:03 -07:00
Amir Bandeali
e9f0f4af86 Rename functions and variables for clarity 2019-09-23 16:38:22 -07:00
Amir Bandeali
ae75aed55e Change verifyingContractAddress -> verifyingContract everywhere 2019-09-23 16:00:37 -07:00
Amir Bandeali
b359738037 Update EIP712 domain separator schema 2019-09-23 15:59:30 -07:00
Amir Bandeali
5ce988957f Fix tests 2019-09-23 15:55:28 -07:00
Xianny
2d77fce99d Re-enable all TypeScript Packages on 3.0 (#2181)
* update with WIP artifacts and wrappers

* Update order-utils to get build:contracts working

* get asset-buyer and asset-swapper building with 3.0

* get testnet-faucets building on 3.0

* re-enable build for most packages
2019-09-23 15:52:51 -07:00
Amir Bandeali
62663ed6d2 Fix rewards tests 2019-09-23 15:34:12 -07:00
Amir Bandeali
3965d8f8c6 Separate wrapping ETH and querying available WETH balance 2019-09-23 15:34:12 -07:00
Amir Bandeali
fd35249de8 Track WETH reserved for rewards 2019-09-23 15:34:12 -07:00
Amir Bandeali
156560ae22 Rename overloaded function 2019-09-23 15:34:12 -07:00
Amir Bandeali
ee687a7dc4 Fix delegator reward unit tests 2019-09-23 15:34:12 -07:00
Amir Bandeali
1710f13242 Fix incorrect return value in _syncPoolRewards 2019-09-23 15:33:10 -07:00
Amir Bandeali
ef645e601c Fix all tests except for reward tests (skipped) 2019-09-23 15:30:55 -07:00
Amir Bandeali
7de23c6af2 Rename variables and functions 2019-09-23 15:30:55 -07:00
Amir Bandeali
639026ea66 Delete vaults and fix contract build 2019-09-23 15:29:36 -07:00
Lawrence Forman
8ddcf88c01 Merge pull request #2155 from 0xProject/feat/staking/hurts-like-a-mbf
Mutli-Block Finalization
2019-09-23 17:51:22 -04:00
Lawrence Forman
3883297991 @0x/contracts-staking: Remove getTotalBalance() function.
`@0x/contracts-staking`: Fix linter errors.
2019-09-23 14:21:18 -04:00
Lawrence Forman
196cc4313f @0x/contract-staking: Make solidity uniformly hideous ;-). 2019-09-23 13:15:51 -04:00
Lawrence Forman
9dd8c61a2f @0x/contract-staking: Address review nits.
`@0x/contracts-utils`: Use `safeDiv()` in `LibFractions.normalize()`.
2019-09-23 11:55:02 -04:00
Lawrence Forman
6d20f0e987 @0x/contracts-staking: Update compiler version in truffle config. 2019-09-22 13:20:47 -04:00
Lawrence Forman
eac4520406 @0x/contracts-staking: Rebase against 3.0 2019-09-22 13:11:42 -04:00
Lawrence Forman
e4126189df @0x/order-utils: Fix staking error codes after rebase. 2019-09-22 13:09:44 -04:00
Lawrence Forman
aa4ee2c166 @0x/dev-utils: Increase gas limit to 9e6 2019-09-22 13:08:59 -04:00
Lawrence Forman
c72a15b488 @0x/contracts-staking: All tests back up and running. 2019-09-22 12:20:42 -04:00
Lawrence Forman
6a29654d7d @0x/contracts-staking: Updating tests and making the contracts testable. 2019-09-22 12:20:04 -04:00
Lawrence Forman
3ad7728a0e @0x/contracts-staking: Remove IStructs.CumulativeRewardInfo, etc.
`@0x/contracts-staking`: Convert all rewards to WETH.
`@0x/contracts-staking`: Style changes.
`@0x/contracts-staking`: Address misc. review comments.
`@0x/contracts-staking`: Make `LibFractions` scaling a separate step.
2019-09-22 12:17:05 -04:00
Lawrence Forman
14c4491b8c @0x/contracts-staking: Add some extra finalizer tests and light refactorings.
`@0x/contracts-staking`: Add finalization-related protocol fees unit tests.
2019-09-22 12:13:24 -04:00
Lawrence Forman
2eff213840 @0x/contracts-staking: Import randomAddress() instead of defining our own. 2019-09-22 12:13:24 -04:00
Lawrence Forman
2bb9b9a8f7 @0x/contracts-test-utils: Ran prettier. 2019-09-22 12:13:24 -04:00
Lawrence Forman
d064543108 @0x/contracts-staking: Add some computeRewardBalanceOfOperator() tests. 2019-09-22 12:13:24 -04:00
Lawrence Forman
0270777cfc @0x/contracts-test-utils: Add hexHash() to hex_utils. 2019-09-22 12:13:24 -04:00
Lawrence Forman
86106713dd @0x/contracts-staking: Gag! All tests passing? 2019-09-22 12:13:24 -04:00
Lawrence Forman
d5bbbe802b @0x/base-contract: Fix linter errors. 2019-09-22 12:13:24 -04:00
Lawrence Forman
b43fa88606 @0x/contracts-staking: All tests but rewards_test working. 2019-09-22 12:13:24 -04:00
Lawrence Forman
54ac1c284b @0x/base-contract: Properly encode BigNumber indexed filter values in getTopicsForIndexedArgs(). 2019-09-22 12:13:24 -04:00
Lawrence Forman
d33080cf08 @0x/contracts-staking: Finalizer tests passing. 2019-09-22 12:11:47 -04:00
Lawrence Forman
b4b6d4d969 @0x/contracts-test-utils: Add shortZip(). 2019-09-22 12:11:47 -04:00
Lawrence Forman
993f05d5ac @0x/contracts-staking: Fixing tests. 2019-09-22 12:11:47 -04:00
Lawrence Forman
ac7f6aef9e @0x/contracts-staking: It compiles! 2019-09-22 12:11:47 -04:00
Lawrence Forman
7fb5ed0b42 @0x/contracts-staking: Add another test case to delegator rewards tests.
`@0x/contracts-staking`: Rename `delegator_reward_balance_test.ts` -> `delegator_reward_test.ts`.
`@0x/contracts-staking`: Last call before rebasing against 3.0.
2019-09-22 12:11:06 -04:00
Lawrence Forman
52b0ba5b05 @0x/contracts-staking: Fix linter errors. 2019-09-22 12:11:06 -04:00
Lawrence Forman
a43b494302 @0x/contracts-staking: All tests passing! 2019-09-22 12:11:06 -04:00
Lawrence Forman
527ec28915 @0x/contracts-utils: Add auto-scaling and zero-value optimizations to LibFractions. 2019-09-22 12:10:41 -04:00
Lawrence Forman
e267a0e855 @0x/contracts-staking: Transition to V3 2019-09-22 12:10:41 -04:00
Lawrence Forman
0196ce18f3 @0x/contracts-staking: Last call before embarking of V3 of staking integration. 2019-09-22 12:10:41 -04:00
Lawrence Forman
7ef3c12722 @0x/contracts-staking: Well, it almost worked. 2019-09-22 12:10:41 -04:00
Lawrence Forman
38b94ec5f8 @0x/order-utils: Add InvalidMinimumPoolStake to StakingRevertErrors.InvalidParamValueErrorCode. 2019-09-22 12:08:14 -04:00
Lawrence Forman
fa65452e2b @0x/contracts-staking: OK, two more finalizer tests. 2019-09-22 12:07:46 -04:00
Lawrence Forman
da0f6b5e8f @0x/contracts-test-utils: Finish off finalizer tests... for now. 2019-09-22 12:07:46 -04:00
Lawrence Forman
b4929df1e6 @0x/order-utils: Ran prettier. 2019-09-22 12:07:46 -04:00
Lawrence Forman
03c59fdaf7 @0x/contracts-staking: More MixinFinalizer unit tests. 2019-09-22 12:07:46 -04:00
Lawrence Forman
f5ab1e6f86 @0x/contracts-staking: Reduce code duplication in MixinFinalizer and add unit tests for it. 2019-09-22 12:07:46 -04:00
Lawrence Forman
ada1de429c @0x/order-utils: Add PreviousEpochNotFinalizedError to StakingRevertErrors. 2019-09-22 12:07:46 -04:00
Lawrence Forman
a1aad2e55e @0x/contracts-exchange: Fixing tests and writing new ones. 2019-09-22 12:07:46 -04:00
Lawrence Forman
d548ddac0d @0x/contracts-staking: Fixing tests. 2019-09-22 12:07:46 -04:00
Lawrence Forman
58a5ab4550 @0x/contracts-test-utils: Allow hexSlice() to take negative numbers, and a range. 2019-09-22 12:07:11 -04:00
Lawrence Forman
6a8242a6ca @0x/contracts-staking: Fix past epoch reward accounting. 2019-09-22 12:07:11 -04:00
Lawrence Forman
46b8bfe338 @0x/contracts-staking: It compiles! (again) 2019-09-22 12:07:11 -04:00
Lawrence Forman
102ca6b854 @0x/contracts-staking: Almost compiling... 2019-09-22 12:07:11 -04:00
Lawrence Forman
06b4d241af @0x/contracts-staking: Working on MBF v2 2019-09-22 12:07:11 -04:00
Lawrence Forman
712b2569e6 @0x/contracts-staking: Fix solidity linter errors. 2019-09-22 12:06:34 -04:00
Lawrence Forman
294be37afc @0x/contracts-staking: Got the solidity compiling. 2019-09-22 12:06:34 -04:00
Lawrence Forman
b57c0a2ebb @0x/contracts-staking: Fully implement MBF (I hope). 2019-09-22 12:05:33 -04:00
Lawrence Forman
94909f1a0f @0x/contracts-staking: Add another delegator payout test. 2019-09-22 12:05:33 -04:00
Lawrence Forman
9c47d22ff4 @0x/contracts-staking: Add some tests to check rewards in the EthVault to _rewards_test. 2019-09-22 12:05:33 -04:00
Lawrence Forman
e4b9d14f45 @0x/contracts-staking: Tinkering with crediting rewards. 2019-09-22 12:05:33 -04:00
Lawrence Forman
73f1aca4a1 @0x/contracts-staking: More work on MixinFinalizer. 2019-09-22 12:05:33 -04:00
Lawrence Forman
bbae6b3de2 @0x/contracts-staking: Starting MBF. 2019-09-22 12:05:33 -04:00
David Sun
e5133a2dd9 prettier 2019-09-21 22:21:55 -04:00
David Sun
ef0096b7d9 added tests 2019-09-21 22:20:11 -04:00
Amir Bandeali
29f4d6918a Merge pull request #2178 from 0xProject/feat/3.0/upgradability-controls
Upgradability controls
2019-09-20 17:47:36 -07:00
Amir Bandeali
45c7653850 Initialize Authorizable instead of Ownable in constructors, fix tests that use onlyOwner modifier 2019-09-20 17:16:35 -07:00
Amir Bandeali
8bdd1d7680 Fix linting errors 2019-09-20 16:55:30 -07:00
Amir Bandeali
a1ed7183ea Fix tests 2019-09-20 16:55:30 -07:00
Amir Bandeali
7b81af2cb4 Change onlyOwner -> onlyAuthorized everywhere 2019-09-20 16:55:30 -07:00
Amir Bandeali
a70a3c9600 Fix SenderNotAuthorizedError class 2019-09-20 16:55:30 -07:00
Amir Bandeali
a14ddbfac2 Make enterCatastrophicFailure callable by any authorized address 2019-09-20 16:55:30 -07:00
Amir Bandeali
e1c57cf0af Refactor Authorizable to use internal methods 2019-09-20 16:55:30 -07:00
Amir Bandeali
522994262d Update tests 2019-09-20 16:55:30 -07:00
Amir Bandeali
f681357eeb Add missing error codes to InvalidParamValueErrorCode 2019-09-20 16:53:58 -07:00
Amir Bandeali
f9b593da59 Lower length of an epoch to 10 days 2019-09-20 16:53:58 -07:00
Amir Bandeali
a340c817c9 Guarantee that makers can't be added to pools when max amount decreases 2019-09-20 16:53:58 -07:00
Amir Bandeali
cc67f732e1 Move storage assertions into StakingProxy 2019-09-20 16:53:58 -07:00
mzhu25
e2ee7e6837 Merge pull request #2164 from 0xProject/feature/contracts-staking/mixin-vault-core-unit-tests
MixinVaultCore unit tests
2019-09-20 16:35:33 -07:00
Michael Zhu
49d223f344 MixinVaultCore unit tests 2019-09-20 16:02:54 -07:00
Lawrence Forman
314d1b9873 Merge pull request #2179 from 0xProject/feat/staking/LibCobbDouglas
Extract `MixinExchangeFees._cobbDouglas()` into LibCobbDouglas
2019-09-20 18:29:40 -04:00
mzhu25
2a391bf947 Merge pull request #2151 from 0xProject/feature/contracts-staking/maintain-global-stake
Maintain global stake
2019-09-20 15:07:05 -07:00
Lawrence Forman
7a33f68138 @0x/contracts-staking: Extract MixinExchangeFees._cobbDouglas() into its own library. 2019-09-20 15:56:26 -04:00
David Sun
48d0b46e43 added utils for fee detection 2019-09-20 15:36:52 -04:00
David Sun
5fe9edce8c Merge pull request #2175 from 0xProject/steveklebanoff-patch-1
Change asset-swapper URL in package.json
2019-09-19 23:29:53 -04:00
Steve Klebanoff
1c038e1f3c Change asset-swapper URL in package.json 2019-09-19 23:29:08 -04:00
Xianny
a57dd427ca Merge development into 3.0 (#2170)
* Added longer timeout for algolia admin operations. Added an option to apply hidden and custom labels to filters from algolia. Added sorting guides (alphabetically) and tools (by community maintenance and alphabetically).

* Fixed some types in guides

* Updated webpack, webpack-dev-server, webpack-bundle-analyzer, webpack-cli versions

* Updated / cleaned up babel and mdx packages

* Updated terser webpack plugin; Removed uglify plugin (unused). Added parallel option for terser. Added target browsers and cache directory option for babel-loader

* Webpack changes: using eval-source-map for development, added parallel option to Terser plugin, added cache loader and caching directory to mdx / babel loaders.

* Removed unusued pkg: body-scroll-lock

* Removed unused jsonschema / @types/jsonschema packages

* Removed unused less node package, adjusted less loader rules to match other loaders in webpack config

* Removed unusued node-sass package. Left sass-loader for webpack intact.

* Removed unused package react-lazyload

* Removed unused package react-typist

* Removed react-tap-event types as it's not used anymore. Reinstalled node-sass as a dev dependency as it's needed by sass-loader

* Moves @0x/types and @0x/typescript-typings to devDependencies

* Replaced react loadable (only used in Icon) with the native react lazy / suspense. Removed loadable nad its types from package.json

* Removed unused make-promises-safe package

* Moved animations to public and compressed files

* Added opening step links in new tab if the url is valid

* Moved @0x/types back to dependencies.

* Added animation wrapper with positioning props. Updated animations for core concepts.

* Replaced images for core concepts. Fixed a bug causing duplicate props on image and its container in mdx

* Remove legacy FAQ

* Update yarn.lock

* Add MD docs diff test to CI

* Remove unused dep

* Update docs to latest format

* Update yarn.lock

* Update ts-doc-gen with fix for multi-link lines

* Final docs gen

* Fix home route

* Update yarn.lock

* Add Golang Mesh RPC package and update versions

* Update the tools MDX files from authoritative S3 before build and dev server start

* Gitignore the tool MDX files in website repo

* Redirect old docs pages and wiki to new doc pages

* Move out Algolia indexing command-line tool out of website and remove need to expose admin key

* Add updating tools from S3 and indexing content on Algolia to deployment commands

* Add note about admin API env var needed for indexing docs

* Remove scripts gitignore since we don't have monorepo scripts in each package anymore

* Segregate indexes by environment

* Fixed 404 display for docs pages

* Removed webpack bundle analyzer

* Fix search and indexing

* Use `yarn` because otherwise the flags don't get passed down properly

* Improve indexing comment

* Remove legacy doc pages

* Fix linter errors

* Fix clean command to remove bundles recursively

* Revert react and react-dom versions in Instant

* Remove old doc md files

* Fix links

* Fix prettier

* Combine @0x/utils exports

* Update doc links

* Remove unused components

* Fix TS error

* Add missing new line

* Update Guides

* Ignore auto-generated MDX in website repo

* Prettier fix

* Add all guides to the sitemap.txt

* Add MMing guide

* Fix Get Started links

* Add 0x Extensions guide

* Replace all links to wiki with links to guides section

* Fix all /docs/{pkg} links to /docs/tools/{pkg}

* Remove deployer endpoint that is no longer used

* Fix links in Core Concepts

* Fixed regex to not remove hashes on links beyond the initial one

* Fixed huge width on instant screenshot

* Cleaned up core concept illustrations

* Started updating tool titles

* Fixed sectionizing headings in docs: Nested sections do not get wrapped in parent sections anymore; only sectionizing headings that need to be sectionized (i.e. that appear in the table of contents)

* Stylstic fix for the new way we sectionize headings / table of contents

* Change CoordinatorWrapper constructor to take a provider

* Added autolinking headings in mdx docs

* Refactor doc generation script to only generate MD docs and to have them reflect what is exported in their respective index.ts files

* Update ts-doc-gen

* Pass in provider, not Web3Wrapper

* Add back logic to prune out private methods

* Write algolia_metadata to utils dir

* Remove duplicate algolia_meta

* Add more packages to those we generate docs for and remove unused flags

* Update reference.mdx files

* Hide tools from homepage that have isHidden flag

* Link 0x.js to it's reference page

* Update tool naming to be more human readable

* Remove order-watcher reference doc

* Add blurb about on-chain API Explorer

* Add "On-chain" prefix to section name

* Remove committed reference file

* Sorting guides by difficulty and alphabetically

* Pushed sorting guides titles case-insensitive

* Sorting tools by difficulty and alphabetically. Removed icons from featured tools. Extracted common difficultyOrder constant

* Update ts-doc-gen so that it properly converts module relative links to anchor links

* Update doc references

* Remove "Relayers" topic/tag

* Prettier fix

* Remove hr so we don't have a bunch in a row

* Cleaned up CLI tag and added link to tools on API page

* Cleaned up some Guide titles

* Added bug bounty program guide

* Fixed a bug in algolia_meta

* Thrid level of nesting / temporary webpack config

* Open help link in new tab

* Link Python tools to doc pages not PyPi

* Fix links in guides

* Remove unused variables

* Revert webpack config

* Extracted common styles for levels of nesting deeper than 1 in the mdx table of contents

* Smoother animation on active table of contents state change

* Autolink headings in mdx only up to h3. Added heading sizes (in px) for h4,h5,h6 in mdx headings

* Fix prettier

* Adjusted font-size for paragraph, ordered and unordered lists. Fixed line-heights and colors too.

* Update ts-doc-gen and the reference docs

* Replace 0xproject.com urls with 0x.org

* Update README links

* Fix header sizes to display optimally in sidebar

* Fixed an issue with other nodes than text being parsed incorrectly in the table of contents

* Fixed styles for table of contents

* Use a different babel plugin that works in a production webpack build

* Unbroke build process / generating toc

* Changed line-height to 1.6 for paragraph

* Adjust scrollbar / toc height to available space

* Fixed some types

* Remove unnecessary link

* Fix casing on TypeScript

* Fix casing of PyPI

* Remove doc gen from abi-gen-wrappers since it'll be tested via contract-wrappers

* Fix MD docs and make sure generated contract wrappers are being rendered

* Remove generated docs in clean

* Correctly copying code samples

* Several additional fixes to the reference MDX docs

* Changed tools to Tools & Libraries - top nav left as just tools

* Changed references from Asset Buyer to Asset Swapper

* Changed trader keyword to trading

* Nevermind, changed back to Trader

* Sneaking in updated product dropdown menu titles based on Will's feedback

* Removed the word wiki from resources dropdown

* Open legal guide in same window

* Removed the isCommunity filter / custom filter labels functionality (only used for that before)

* Update ts-doc-gen version to one that fixes issues with Object Literals and removes Hierarchy sections and Module headers

* update yarn.lock

* Remove unused code

* Remove unused import

* Remove unused imports

* Remove unused import

* Fix prettier

* Update outdating dep version

* Created a color scheme for code snippets. Fixed language not being passed to some code blocks in two guides.

* Update abi-gen-wrappers dep version

* Update Algolia to production account

* Fix prettier

* Fix prettier in algolia_meta

* Remove packages/dev-tools-pages folder and update yarn.lock

* Remove other random references to dev-tools-pages

* Fix website

* Changed the order of indices in search suggestions

* Removed a comment

* Added scrollbar size adjustment on resize / scroll

* Rendering sidebar on mobile without any event listeners / taxing calculations / changes in height

* Added a performance comment

* Simplified table of contents

* Update ganache-cli to later version

* Remove bundle dirs too

* Added keeping active link in view when scrolling content in the docs

* Increase available memory for webpack

* Update contract addresses

* Update market-making guide to mention Mesh as an alternative to SRA

* Update Web3 Provider Explained guide

* Re-wrote Ganache Setup guide into a Setting up a local 0x testnet guide

* Export more of abi-gen-wrappers from contract-wrappers

* Final update of reference docs

* Add contract-wrappers MD docs and update it's index.ts so that no types are missing

* Fix prettier

* Increase the memory allocation for building the website

* Remove use of remove type

* Check if link is a valid url in mdx inline link: if so, open in a new tab, if not, same tab.

* Print out which snapshot version is being downloaded

* Updated CHANGELOGS & MD docs

* Publish

 - @0x/contracts-asset-proxy@2.2.7
 - @0x/contracts-coordinator@2.0.12
 - @0x/contracts-dev-utils@0.0.9
 - @0x/contracts-erc1155@1.1.14
 - @0x/contracts-erc20@2.2.13
 - @0x/contracts-erc721@2.1.14
 - @0x/contracts-exchange-forwarder@3.0.11
 - @0x/contracts-exchange-libs@3.0.7
 - @0x/contracts-exchange@2.1.13
 - @0x/contracts-extensions@4.0.7
 - @0x/contracts-multisig@3.1.13
 - @0x/contracts-test-utils@3.1.15
 - @0x/contracts-utils@3.2.3
 - 0x.js@7.0.1
 - @0x/abi-gen-wrappers@5.3.1
 - @0x/abi-gen@4.2.0
 - @0x/assert@2.1.5
 - @0x/asset-buyer@6.1.13
 - @0x/asset-swapper@1.0.3
 - @0x/base-contract@5.3.3
 - @0x/connect@5.0.18
 - @0x/contract-artifacts@2.2.1
 - @0x/contract-wrappers@12.0.0
 - @0x/contracts-gen@1.0.14
 - @0x/dev-tools-pages@0.0.30
 - @0x/dev-utils@2.3.2
 - ethereum-types@2.1.5
 - @0x/fill-scenarios@3.0.18
 - @0x/instant@1.0.30
 - @0x/json-schemas@4.0.1
 - @0x/migrations@4.3.1
 - @0x/monorepo-scripts@1.0.36
 - @0x/order-utils@8.3.1
 - @0x/sol-compiler@3.1.14
 - @0x/sol-coverage@3.0.11
 - @0x/sol-doc@2.0.18
 - @0x/sol-profiler@3.1.13
 - @0x/sol-resolver@2.0.10
 - @0x/sol-trace@2.0.19
 - @0x/sol-tracing-utils@6.0.18
 - @0x/sra-spec@2.0.16
 - @0x/subproviders@5.0.3
 - @0x/testnet-faucets@1.0.86
 - @0x/types@2.4.2
 - @0x/typescript-typings@4.2.5
 - @0x/utils@4.5.1
 - @0x/web3-wrapper@6.0.12
 - @0x/website@0.0.89

* Remove the website from the monorepo

* Update yarn.lock

* Remove website files that were accidentally merged back in

* Use local EVM for pure functions (#2108)

* add local evm for pure functions

* increase container size to >=8gb for static-tests

* increase max bundle size because of ethereumjs-vm dependency

* add declarations for ethereumjs-vm in @0x/typescript-typings

* Make `OrdersChannelSubscriptionOpts` conform to SRAv2

* Make it easier to use validateOrderFillableOrThrowAsync (#2096)

* make it easier to use validateOrderFillableOrThrowAsync

* add unit tests, use DevUtils

* remove dependency on @0x/order-utils from @0x/migrations

* add devUtils to contract-wrappers (#2146)

* Delete docs in S3 bucket before uploading latest version so we only ever have one version uploaded at a time

* Update to new ts-doc-gen version that fixes links in "Inherited from" lines

* try to fix instant build

* Remove redoc-cli as a dep from sra-spec

* Smooth out some last incompatible types

* Fix prettier

* Add terser-webpack-plugin to 0x.js deps

* @0x/orderbook

* AssetSwapper to use @0x/orderbook

* Remove unused imported type

* Prevent double websocket connections

* Fix build error

* fixed consumer inconsistency bug

* linted + added convenience functionality

* minor changes/typo fixes

* updated websocket

* updated for prettier

* Fix versions and exported types

* move log tests to @0x/abi-gen; delete exchange_wrapper_test (#2160)

* Remove unused exported types

* Fix exports from asset-swapper

* Update exported types for docs

* Update mesh client dep

* Move perPage and 18 precision lower to re-use

* fix ABI encoding/decoding functions (#2165)

* Fix typo at contract import (#2102)

* Updated CHANGELOGS & MD docs

* Publish

 - @0x/contracts-asset-proxy@2.2.8
 - @0x/contracts-coordinator@2.0.13
 - @0x/contracts-dev-utils@0.0.10
 - @0x/contracts-erc1155@1.1.15
 - @0x/contracts-erc20@2.2.14
 - @0x/contracts-erc721@2.1.15
 - @0x/contracts-exchange-forwarder@3.0.12
 - @0x/contracts-exchange-libs@3.0.8
 - @0x/contracts-exchange@2.1.14
 - @0x/contracts-extensions@4.0.8
 - @0x/contracts-multisig@3.1.14
 - @0x/contracts-test-utils@3.1.16
 - @0x/contracts-utils@3.2.4
 - 0x.js@7.0.2
 - @0x/abi-gen-wrappers@5.3.2
 - @0x/abi-gen@4.2.1
 - @0x/assert@2.1.6
 - @0x/asset-buyer@6.1.14
 - @0x/asset-swapper@2.0.0
 - @0x/base-contract@5.4.0
 - @0x/connect@5.0.19
 - @0x/contract-addresses@3.2.0
 - @0x/contract-artifacts@2.2.2
 - @0x/contract-wrappers@12.1.0
 - @0x/contracts-gen@1.0.15
 - @0x/dev-utils@2.3.3
 - ethereum-types@2.1.6
 - @0x/fill-scenarios@3.0.19
 - @0x/instant@1.0.31
 - @0x/json-schemas@4.0.2
 - @0x/migrations@4.3.2
 - @0x/monorepo-scripts@1.0.37
 - @0x/order-utils@8.4.0
 - @0x/orderbook@0.0.2
 - @0x/sol-compiler@3.1.15
 - @0x/sol-coverage@3.0.12
 - @0x/sol-doc@2.0.19
 - @0x/sol-profiler@3.1.14
 - @0x/sol-resolver@2.0.11
 - @0x/sol-trace@2.0.20
 - @0x/sol-tracing-utils@6.0.19
 - @0x/sra-spec@2.0.17
 - @0x/subproviders@5.0.4
 - @0x/testnet-faucets@1.0.87
 - @0x/types@2.4.3
 - @0x/typescript-typings@4.3.0
 - @0x/utils@4.5.2
 - @0x/web3-wrapper@6.0.13

* fix circleci diff

* update changelog
2019-09-19 19:43:08 -07:00
Amir Bandeali
2253f214a6 Merge pull request #2138 from 0xProject/feat/3.0/update-apowner
Update AssetProxyOwner
2019-09-19 14:52:19 -07:00
Amir Bandeali
ad11dc2421 Remove unnecessary sload 2019-09-19 13:41:02 -07:00
Amir Bandeali
bd3b200b30 Add extra tests 2019-09-19 13:41:02 -07:00
Amir Bandeali
0d259d13b9 Fix base multisig style 2019-09-19 13:40:57 -07:00
Amir Bandeali
6fd55b2f49 Add more tests 2019-09-19 13:37:59 -07:00
Amir Bandeali
057aee8ad2 Fix linting errors 2019-09-19 13:37:59 -07:00
Amir Bandeali
f47feabb4a Update AssetProxyOwner tests 2019-09-19 13:37:59 -07:00
Amir Bandeali
eb784a4a7c Update test contracts 2019-09-19 13:37:59 -07:00
Amir Bandeali
5d30c957cb Update AssetProxyOwner to allow batch transactions and custom timelocks 2019-09-19 13:37:59 -07:00
Amir Bandeali
585adef75d Add revert reasons to bbase MultiSigWallet 2019-09-19 13:37:59 -07:00
Amir Bandeali
2f07fcc81c Upgrade Base MultiSigs to Solidity 0.5.9 2019-09-19 13:37:59 -07:00
F. Eugene Aumson
1d55d12c8f Deployed DevUtils address, & artifact used (#2176) 2019-09-19 07:00:37 -04:00
F. Eugene Aumson
bca8c5eccc DevUtils.sol: Upgrade for v3 (#2161)
* Exhibit bug in getSimulatedOrderTransferResults

* Fix getSimulatedOrderTransferResults

* dev-utils/package.json: add quantify_bytecode cmd

* Fix typo in log message

* Reduce compiler optimization runs

In order to reduce the EVM bytecode object length of the DevUtils
contract to be under the EIP-170 limit of 24 KB.
2019-09-18 19:36:06 -04:00
Michael Zhu
f7462c9f2b keep track of globalStakeByStatus + tests 2019-09-18 10:09:45 -07:00
Greg Hysz
549697dc47 Merge pull request #2156 from 0xProject/feature/staking/syncingRewards
Sync Rewards + Refactored Reward Vault
2019-09-17 21:02:28 -07:00
Greg Hysen
2869dd3bac Removed unnecessary sloads in MixinStakingPoolMakers 2019-09-17 20:32:49 -07:00
Greg Hysen
5a225795e1 Updated changelog and ran linter 2019-09-17 17:51:16 -07:00
Greg Hysen
877abeda63 Removed MixinStakingPoolRewards 2019-09-17 17:37:24 -07:00
Greg Hysen
768387fea9 Rebased and addressed PR comments 2019-09-17 17:37:12 -07:00
Greg Hysen
db97fe8164 updated changelog 2019-09-17 17:36:47 -07:00
Greg Hysen
be1a70c461 refactored the staking vault 2019-09-17 17:36:46 -07:00
Amir Bandeali
b631fc610b Merge pull request #2169 from 0xProject/fix/3.0/fix-breaking-tests
Fix breaking tests, remove MixinZrxVault
2019-09-17 16:16:38 -07:00
Amir Bandeali
9b2672841d Fix build and tests 2019-09-17 15:51:46 -07:00
Amir Bandeali
336e8bafb4 Remove MixinZrxVault 2019-09-17 15:51:41 -07:00
Amir Bandeali
2ea354f748 Merge pull request #2166 from 0xProject/feat/3.0/staking-upgradability
Staking params upgradability
2019-09-17 14:20:25 -07:00
Amir Bandeali
2d125cdc20 Fix typos and remove redundant cached variables 2019-09-17 13:50:18 -07:00
Amir Bandeali
0d441a829f Add missing checks to attachStakingContract tests 2019-09-17 13:01:56 -07:00
Amir Bandeali
ee5cb6909c Merge pull request #2158 from 0xProject/feat/3.0/cleanup-staking-contracts
Change state var visibilities, delete redundant code
2019-09-17 12:57:51 -07:00
mzhu25
5258053dc8 Merge pull request #2152 from 0xProject/feature/contracts-staking/ensure-delegate-pool-exists
Ensure pool exists before (un)delegating
2019-09-17 11:29:51 -07:00
Amir Bandeali
bb46f184ed Remove use of generatePseudoRandomAddress in favor of randomAddress 2019-09-17 10:46:58 -07:00
Michael Zhu
7cc1304eca Revert when attempting to delegate to/undelegate from a pool that doesn't exist 2019-09-17 10:29:57 -07:00
Amir Bandeali
94738444de Fix build an tests 2019-09-17 09:41:27 -07:00
Amir Bandeali
4705b15188 Add addresses back as optional params to attachStakingContract 2019-09-17 08:48:14 -07:00
Amir Bandeali
de567da846 Fix typo across files 2019-09-17 08:48:14 -07:00
Amir Bandeali
6641af2a58 Fix build 2019-09-17 08:48:14 -07:00
Amir Bandeali
de9527ce2f Do not initialize stakingProxy in vault constructors 2019-09-17 08:48:14 -07:00
Amir Bandeali
16ebdfad9a Remove redundant setters and require statements 2019-09-17 08:47:19 -07:00
Amir Bandeali
b70db37b4f Set wethAssetProxy, ethVault, rewardVault, and zrxVault using init pattern 2019-09-17 08:47:19 -07:00
Amir Bandeali
3843c64c40 Update visibility, events, and naming in vaults 2019-09-17 08:45:56 -07:00
Amir Bandeali
1d1dd4b6a2 Do not shadow _ethVault 2019-09-16 22:50:47 -07:00
Amir Bandeali
d3a9ace5fd Fix linting errors 2019-09-16 22:50:47 -07:00
Amir Bandeali
778c57320c Update function visibilities 2019-09-16 22:50:47 -07:00
Amir Bandeali
f98f3660f9 Add back balanceOf getters in vaults, remove public variable getters from inherited interfaces 2019-09-16 22:50:47 -07:00
Amir Bandeali
fd4141e1f3 Fix build 2019-09-16 22:50:11 -07:00
Amir Bandeali
97c107be3e Fix unused stack variable and add missing devdoc comment 2019-09-16 22:50:11 -07:00
Amir Bandeali
2eada9db62 Add IStorage interface 2019-09-16 22:49:25 -07:00
Amir Bandeali
e9362439c3 Make some storage vars public and rename internal vars 2019-09-16 22:48:32 -07:00
Amir Bandeali
a2419ab31d Fix getTotalProtocolFeesThisEpoch by adding weth balance 2019-09-16 22:34:55 -07:00
Amir Bandeali
e589f10e23 Cleanup imports 2019-09-16 22:34:55 -07:00
Greg Hysz
5d84d40a2c Merge pull request #2154 from 0xProject/feature/staking/refCountRewards
Reference counting for rewards, plus unit tests for cumulative rewards tracking
2019-09-16 19:20:55 -07:00
Greg Hysen
43d1d0b217 more explicit sanity checks for computing balance in interval (previously all failed with div-by-zero)
typos
2019-09-16 18:57:21 -07:00
James Towle
0f802d5a1b Merge pull request #2153 from 0xProject/feature/staking/batch-execute
Implement Batch Execute Transaction
2019-09-16 17:20:33 -07:00
Alex Towle
56efde6e34 @0x:contracts-staking Addressed final review comment 2019-09-16 16:59:50 -07:00
Greg Hysen
e224e6cde5 updated changelog 2019-09-16 16:03:40 -07:00
Greg Hysen
e1d51bae73 Tests are passing and ran linter 2019-09-16 16:02:50 -07:00
Greg Hysen
f9163ccc01 Improved readability of API for cumulative rewards 2019-09-16 15:18:08 -07:00
Alex Towle
6353bf545d @0x:contracts-staking Addressed lingering review comments 2019-09-16 10:33:39 -07:00
Greg Hysen
12f0797ace Reference counting for rewards, plus unit tests for cumulative rewards. 2019-09-14 00:04:52 -07:00
mzhu25
c9de423fb8 LibSafeDowncast unit tests (#2143) 2019-09-13 16:09:46 -07:00
Alex Towle
2cd0990c65 @0x:contracts-staking Addressed review feedback by removing simplyProxyCallWithData 2019-09-13 15:41:31 -07:00
Alex Towle
6fd9308e1b @0x:contract-staking Added integration tests for 2019-09-12 18:17:00 -07:00
Alex Towle
1fc57baac1 @0x:contracts-staking Added tests for simpleProxyCallWithData() 2019-09-12 17:38:39 -07:00
Alex Towle
2ed63970d4 @0x:contracts-staking Add a batchExecute function to the staking contracts 2019-09-12 17:12:14 -07:00
James Towle
7ba6c601e5 Merge pull request #2142 from 0xProject/test/staking/lib-proxy
Test/staking/lib proxy
2019-09-12 13:50:32 -07:00
Alex Towle
cc43c5b28c @0x:contracts-staking Cleaned up combinatorial tests 2019-09-12 12:30:25 -07:00
Alex Towle
b7f25ee3b6 @0x:contracts-staking Addressed review comments 2019-09-11 17:16:33 -07:00
Alex Towle
82afdda256 @0x:contracts-staking Fixed compilation errors and ran prettier 2019-09-11 17:16:33 -07:00
Alex Towle
be83789bee @0x:contracts-staking Added unit tests for LibProxy 2019-09-11 17:15:47 -07:00
Alex Towle
036c8fe920 @0x:contracts-staking Fixed style issues in staking RichErrors 2019-09-11 17:11:04 -07:00
Lawrence Forman
b7b125f623 Merge pull request #2131 from 0xProject/feature/staking/hyper-init
Staking: Hyper-Parameters, init() Pattern, Dust Stake
2019-09-10 21:57:04 -04:00
Lawrence Forman
060edf33bd @0x/contracts-staking: Fix compilation error in MixinParams. 2019-09-10 16:30:50 -04:00
Lawrence Forman
656120cd1f @0x/contracts-staking: Rename InvalidParamValue RevertError to InvalidParamValueError. 2019-09-10 15:32:40 -04:00
Lawrence Forman
34acd71835 @0x/order-utils: Rename InvalidParamValue RevertError to InvalidParamValueError. 2019-09-10 15:31:19 -04:00
Lawrence Forman
7eb4bebac3 @0x/contracts-staking: Fix typos. 2019-09-10 00:58:33 -04:00
Lawrence Forman
f45ee486e9 @0x/contracts-staking: Rebase against 3.0 AGAIN AGAIN AGAIN AGAIN AGAIN 2019-09-10 00:45:20 -04:00
Lawrence Forman
3b28c9d5a7 @0x/order-utils: Rename OperatorShareMustBeBetween0And100 to OperatorShareTooLarge. 2019-09-10 00:39:45 -04:00
Lawrence Forman
2ed39cd18d @0x/contracts-staking: Rename Tuned event to ParamsChanged.
`@0x/contracts-staking`: Merge `exchange_fees` unit tests into `protocol_fees` unit tests.
`@0x/contracts-staking`: Remove `ProtocolFeeActor` and any use of it.
`@0x/contracts-staking`: Remove unused constants.
`@0x/contracts-staking`: Move WETH assertion constructor into `MixinDeploymentConstants`.
`@0x/contracts-staking`: Add more unit tests.
2019-09-10 00:32:43 -04:00
Lawrence Forman
d8d791e4f0 @0x/order-utils: Remove redundant InvalidStakeStatusError in registry. 2019-09-10 00:32:43 -04:00
Lawrence Forman
89bd42de04 @0x/contracts-staking: Fix linter errors. 2019-09-10 00:32:43 -04:00
Lawrence Forman
51b460d432 @0x/contracts-staking: Rebase against 3.0 2019-09-10 00:32:43 -04:00
Lawrence Forman
6410366f8b @0x/contracts-staking: Fix contracts formatting.
`@0x/contracts-staking`: Remove typo test suite in `migration.ts`.
`@0x/contracts-staking`: Address minor review comments.
2019-09-10 00:32:43 -04:00
Lawrence Forman
1c2f4906e6 @0x/contracts-exchange: Remove signature-related IStructs structs.
`@0x/contracts-exchange`: Create some `payProtocolFee()` unit tests to test new staking minimum.
2019-09-10 00:32:30 -04:00
Lawrence Forman
bed90fa8ec @0x/contracts-staking: Update changelog. 2019-09-10 00:31:51 -04:00
Lawrence Forman
25787ea806 @0x/contracts-staking: Rename MixinHyperParameters -> MixinParams.
`@0x/contracts-staking`: Move params storage variables into `MixinStorage`.
`@0x/contracts-staking`: Add storage layout tests for new state vars.
`@0x/contracts-staking`: Add more migration tests.
`@0x/contracts-staking`: Add `_initMixinParams()` function that sets up `MixinParams` state.
2019-09-10 00:31:50 -04:00
Lawrence Forman
2a21d87193 @0x-order-utils: Rename InvalidTuningValue -> InvalidParamValue. 2019-09-10 00:31:24 -04:00
Lawrence Forman
7cee17887a @0x/order-utils: Add MxinParamsAlreadyInitialized to StakingRevertErrors.InitializationErrorCode. 2019-09-10 00:31:24 -04:00
Lawrence Forman
0cc94bcf19 @0x/contracts-staking: Add maximumMakersInPool hyper parameter.
`@0x/contracts-staking`: Add assertions against `maximumMakersInPool` and `rewardDelegatedStakeWeight`.
`@0x/contracts-staking`: Rebase against 3.0 (again).
2019-09-10 00:31:24 -04:00
Lawrence Forman
a554ae904f @0x/order-utils: Add InvalidRewardDelegatedStakeWeight and InvalidMaximumMakersInPool to InvalidTuningValueErrorCode. 2019-09-10 00:31:24 -04:00
Lawrence Forman
9dcda6113d @0x/contracts-staking: Rebase against 3.0. 2019-09-10 00:31:24 -04:00
Lawrence Forman
7d50117903 @0x/contract-staking: Refactor out contract attach logic so it's shared between the constructor and attachStakingContract().
`@0x/contract-staking`: Introduce migration tests to test the `init()` pattern.
2019-09-10 00:31:24 -04:00
Lawrence Forman
76c5517739 @0x/contract-staking: Update CHANGELOG.
`@0x/contract-staking`: Add `DEFAULT_HYPER_PARAMETERS` to test constants.
`@0x/contract-staking`: Appease linter gods.
`@0x/contract-staking`: Remove `setCobbDouglasAlpha()` tests.
`@0x/contract-staking`: Add `tune()` tests.
2019-09-10 00:31:24 -04:00
Lawrence Forman
b9d243e70e @0x/order-utils: Add InitializationError, InvalidTuningValue to StakingRevertErrors. 2019-09-10 00:31:24 -04:00
Lawrence Forman
d37679c129 @0x/contracts-test-utils: Add Numberish type. 2019-09-10 00:30:43 -04:00
Lawrence Forman
d01cfee455 @0x/contracts-staking: Add getHyperParameters() to MixinHyperParameters. 2019-09-10 00:30:43 -04:00
Lawrence Forman
182d360302 @0x/contracts-storage: Move init() out of IStaking and into IStorageInit. 2019-09-10 00:30:43 -04:00
Lawrence Forman
0d9069ecfe @0x/contracts-staking: Fix compilation issues.
`@0x/contracts-staking`: Check that `Staking.init()` succeded.
`@0x/contracts-staking`: Flip some functions from `view` to `pure`.
2019-09-10 00:30:43 -04:00
Lawrence Forman
6488f91e6e @0x/contracts-staking: Replace MixinDeploymentConstants with MixinHyperParameters.
`@0x/contracts-staking`: Add `init()` to `Staking` contract.
`@0x/contracts-staking`: Add `_initMixinScheduler()` to `MixinScheduler`.
`@0x/contracts-staking`: Automaticallly call `Staking.init()` in `StakingProxy.attachStakingContract()`.
`@0x/contracts-staking`: Remove `setCobbDouglasAlpha()` in favor of `tune()`.
`@0x/contracts-staking`: Exclude pools with `stake < minimumPoolStake` in `payProtocolFee()`.
2019-09-10 00:30:43 -04:00
mzhu25
70db4d8847 Merge pull request #2113 from 0xProject/feature/contracts-staking/decrease-operator-share
Move pool operator logic to vault and allow operators to decrease operatorShare
2019-09-09 21:08:01 -07:00
Michael Zhu
faa0d83013 remove unnecessary pointer variable 2019-09-09 17:41:18 -07:00
Michael Zhu
6f1f226ed0 Use storage pointer to update Pool structs, test decreaseStakingPoolOperatorShare where newOperatorShare == oldOperatorShare 2019-09-09 17:11:00 -07:00
Michael Zhu
1d6406bbd6 move operator from staking logic to vault, allow operator to decrease operatorShare 2019-09-09 16:29:19 -07:00
mzhu25
91cee9c648 Merge pull request #2129 from 0xProject/features/contracts-staking/rip-staking-wrapper
Remove StakingWrapper
2019-09-09 16:28:35 -07:00
Michael Zhu
6d83b2676e rip staking_wrapper.ts, use wrapped staking proxy pattern instead 2019-09-09 15:47:15 -07:00
James Towle
c21bce9641 Merge pull request #2130 from 0xProject/feature/staking/protocol-fees
Feature/staking/protocol fees
2019-09-09 15:13:33 -07:00
Alex Towle
1d5c175316 @0x:contracts-staking Fixed lingering review comments 2019-09-09 14:27:44 -07:00
Alex Towle
2fdd4e9760 @0x:contracts-staking Addressed some review comments 2019-09-09 10:25:19 -07:00
Amir Bandeali
abd479dc68 Merge pull request #2139 from 0xProject/feat/3.0/optimize-match-orders
Optimize batchMatchOrders, consolidate TransactionSignatureError rich revert
2019-09-08 21:18:02 -07:00
Amir Bandeali
67ef17f929 Consolidate TransactionSignatureError with SignatureError 2019-09-08 18:55:42 -07:00
Amir Bandeali
35bf179b70 Clear compiler warnings 2019-09-07 22:20:47 -07:00
Amir Bandeali
10c62c10aa Use _getOrderHashAndFilledAmount instead of getOrderInfo to reduce sloads 2019-09-07 22:10:46 -07:00
Amir Bandeali
8317628c61 Create internal function that calculates orderHash and orderTakerAssetFilledAmount 2019-09-07 22:10:05 -07:00
Alex Towle
30fee43928 @0x:contracts-staking Added tests for protocol fees 2019-09-07 13:44:04 -07:00
Alex Towle
494dc475c1 @0x:contracts-staking Added WETH support to MixinExchangeFees 2019-09-07 13:41:27 -07:00
mzhu25
3a503c61b3 Merge pull request #2104 from 0xProject/feature/contracts-staking/maker-join-pool
Reimplement Makers joining Pools
2019-09-06 16:35:16 -07:00
Michael Zhu
86a28f0d19 New logic for makers joining pools 2019-09-06 16:09:35 -07:00
Greg Hysz
24af39d4a8 Merge pull request #2133 from 0xProject/feature/exchange-libs/boundaryCheckOnGetStructHash
Sanity check on order offset when hashing
2019-09-06 16:02:32 -07:00
Greg Hysz
97773e3f64 Merge pull request #2128 from 0xProject/feature/staking/ReadOnlyProxy
Read-Only mode in proxy
2019-09-06 15:46:17 -07:00
Greg Hysen
1dc1218bfc Sanity check on order offset when hashing 2019-09-06 15:40:47 -07:00
Greg Hysen
b458026358 Readability improvements ... apparently I still cant spell catastrophe. 2019-09-06 15:09:16 -07:00
Amir Bandeali
b30a33eef5 Merge pull request #2132 from 0xProject/feat/3.0/flexible-market-fills
Remove restrictions on maker/takerAssetData for marketBuy/Sell functions
2019-09-06 15:05:37 -07:00
Amir Bandeali
0e96a1c8ba Remove restrictions that maker/takerAssetData must be the same for each order in marketBuy/Sell functions 2019-09-06 14:34:16 -07:00
Greg Hysz
f477c0fcc2 Merge pull request #2118 from 0xProject/feature/staking/NewMechanicsSolidityOnly-Squashed
New staking mechanics
2019-09-06 14:12:40 -07:00
Greg Hysen
2ad6dd1ee8 appeased solhint 2019-09-05 14:34:36 -07:00
Greg Hysen
87cfe1a8c6 abstracted out delegate calls into their own library 2019-09-05 14:09:13 -07:00
Greg Hysen
d0c6d9cf2d Read-Only mode in proxy 2019-09-05 14:07:02 -07:00
Greg Hysz
fc7f2e7fc6 Merge pull request #2126 from 0xProject/feature/staking/NewMechanicsSolidityOnly-Squashed-Tests-Squashed
Tests for new staking mechanics
2019-09-05 13:19:49 -07:00
Greg Hysen
49baafadc1 updated changelogs 2019-09-05 12:37:54 -07:00
Greg Hysen
24e62feadf Fixed linter 2019-09-05 12:27:44 -07:00
Greg Hysen
67079d96af Got build to work after rebase 2019-09-05 12:27:43 -07:00
Greg Hysen
5ac4c72f1a current -> currentEpochBalance and next -> nextEpochBalance 2019-09-05 12:27:43 -07:00
Greg Hysen
deceed37f3 Stake State -> Status in tests 2019-09-05 12:27:43 -07:00
Greg Hysen
4bc84cd526 Rich reverts in tests plus readability 2019-09-05 12:27:43 -07:00
Greg Hysen
293c428186 Tests for new staking mechanics 2019-09-05 12:27:43 -07:00
Greg Hysen
d1b004ffc1 Some readability plus updated changelogs 2019-09-05 12:26:04 -07:00
Greg Hysen
da83f75a13 Readability Improvements 2019-09-05 11:54:16 -07:00
Greg Hysen
b5be162fa2 Removed frivolous imports to improve readability 2019-09-05 11:50:22 -07:00
Greg Hysen
7e5e2241cb Rich Reverts in new staking mechanics 2019-09-05 11:50:22 -07:00
Greg Hysen
c0cb78bb3f Improving readability of staking 2019-09-05 11:46:50 -07:00
Greg Hysen
eb6ad7d29d New staking mechanics: delay on entry opposed to exit 2019-09-05 11:45:11 -07:00
Lawrence Forman
88e56356c4 Merge pull request #2109 from 0xProject/feature/3.0/staking/math-voodoo
Staking math upgrades
2019-09-05 13:05:25 -04:00
Lawrence Forman
356660ad4f @0x/contracts-staking: Remove redundant "FixedMath" prefix from FixedMath revert errors. 2019-09-04 20:18:55 -04:00
Lawrence Forman
7c3567f5e7 @0x/utils: Remove redundant FixedMath prefix from FixedMath RevertError types. 2019-09-04 20:18:55 -04:00
Lawrence Forman
e9eb3badd9 @0x/contracts-staking: Keep fees not associated with a pool. 2019-09-04 20:18:55 -04:00
Lawrence Forman
9bbbaadcf8 @0x/conracts-staking: Fix idiotic linter error. 2019-09-04 20:18:55 -04:00
Lawrence Forman
19f44fac1e @0x/contracts-staking: Reformulate cobb-douglas to be more efficient.
`@0x/contracts-staking`: Remove some unecessary asserts.
`@0x/contracts-staking`: Fix some broken test assertions.
`@0x/contracts-staking`: Generate better random values in tests.
`@0x/contracts-staking`: Rename `PPM_ONE` constant to `PPM_DENOMINATOR`.
`@0x/contracts-staking`: Minor solidity code improvements.
`@0x/contracts-staking`: Use more constants from `@0x/contracts-test-utils` in tests.
2019-09-04 20:18:55 -04:00
Lawrence Forman
0be2c250ef Commit yarn.lock 2019-09-04 20:18:55 -04:00
Lawrence Forman
b07fc95c81 @0x/utils: Add docstring for raw constructor parameter in RevertError.
`@0x/utils`: Use `...is.instanceof()` pattern in `RevertError` tests.
2019-09-04 20:18:55 -04:00
Lawrence Forman
20ba23fe5f @0x/contracts-test-utils: Allow negative values in toHex().
`@0x/contracts-test-utils`: Add `PPM_DENOMINATOR` and `PPM_100_PERCENT` constants.
2019-09-04 20:18:55 -04:00
Lawrence Forman
b78705120e @0x/contracts-utils: Fix failing tests due to RevertError behavior changes. 2019-09-04 20:18:55 -04:00
Lawrence Forman
f601329a47 @0x/utils: Rename length field to len in AuthorizableRevertErrors.IndexOutOfBoundsError. 2019-09-04 20:18:55 -04:00
Lawrence Forman
2b3e7e7ab7 @0x/dev-utils: Remove no longer applicable test case in chai_test.ts. 2019-09-04 20:18:55 -04:00
Lawrence Forman
8d5e28f099 @0x/contracts-staking: Change the way operator stake is computed.
`@0x/contracts-staking`: Denominate pool operator shares in parts-per-million.
`@0x/contracts-staking`: Update tests for new stake computation and higher precision math.
`@0x/contracts-staking`: Add `setCobbDouglasAlpha()` function.
2019-09-04 20:18:55 -04:00
Lawrence Forman
cb1dc92594 @0x/order-utils: Rename OperatorShareMustBeBetween0And100Error RevertError type to InvalidPoolOperatorShareError. 2019-09-04 20:18:55 -04:00
Lawrence Forman
495bf08498 @0x/utils: Update CHANGELOG. 2019-09-04 20:18:55 -04:00
Lawrence Forman
a1a5bdce78 @0x/order-utils: Prettier. 2019-09-04 20:18:55 -04:00
Lawrence Forman
f724212fd7 @0x/utils: Prettier. 2019-09-04 20:18:55 -04:00
Lawrence Forman
5ccbe167a1 @0x/contracts-test-utils: Increase the number of ganache accounts to 20. 2019-09-04 20:18:55 -04:00
Lawrence Forman
2e357ffeab @0x/dev-utils: Add total_accounts option to Web3Config. 2019-09-04 20:18:55 -04:00
Lawrence Forman
af10f52acf @0x/contracts-staking: Rebase with 3.0 2019-09-04 20:18:55 -04:00
Lawrence Forman
ed8a6bb97b @0x/contracts-staking: Emit CobbDouglasAlphaChanged event when calling setCobbDouglasAlpha(). 2019-09-04 20:18:55 -04:00
Lawrence Forman
c774b98002 @0x/contracts-staking: Remove unused tslint directives. 2019-09-04 20:18:55 -04:00
Lawrence Forman
9a63bea763 @0x/contracts-staking: Update LibFixedMath ln() and exp() input domains and improve precision.
`@0x/contracts-staking`: Add `_invert()` and `_mulDiv()` to `LibFixedMath`.
`@0x/contracts-staking`: Update `MixinExchangeFees._cobbDouglas()` to work with `LibFixedMath`.
`@0x/contracts-staking`: Add unit and fuzz tests for `_cobbDouglas()` and remaining `LibFixedMath` functions.
2019-09-04 20:18:55 -04:00
Lawrence Forman
0c6a6743ab @0x/contracts-staking: Write LibFixedMath unit tests. 2019-09-04 20:18:55 -04:00
Lawrence Forman
1c37334b18 @0x/contracts-staking: Add a bunch of LibFixedMath unit tests. 2019-09-04 20:18:55 -04:00
Lawrence Forman
7f40665a0e @0x/utils: Fix order of BinOpErrorCodes enum in FixedMathRevertErrors. 2019-09-04 20:18:55 -04:00
Lawrence Forman
b10036444d @0x/order-utils: Add TransactionInvalidContextError to the RevertError registry. 2019-09-04 20:18:55 -04:00
Lawrence Forman
0542c70d22 @0x/utils: Make decoding of unknown selectors to RawRevertError optional. 2019-09-04 20:16:44 -04:00
Lawrence Forman
f71484c9f0 @0x/order-utils: Add TransactionGasPriceError to error registry. 2019-09-04 20:16:44 -04:00
Lawrence Forman
2cf74a7a96 @0x/utils: Make RevertError.decode() return a RawRevertError if the selector is unknown. 2019-09-04 20:15:16 -04:00
Lawrence Forman
018bcf273f @0x/utils: Fix FixedMathRevertError.FixedMathBinOpError type.
`@0x/utils`: Have Ganache `Error` -> `RevertError` coercion fail if it can't look up the selector.
2019-09-04 20:15:15 -04:00
Lawrence Forman
1a3da4b363 @0x/utils: Fix registering FixedMathSignedValueError twice. 2019-09-04 20:15:15 -04:00
Lawrence Forman
0999805b3a @0x/contracts-test-utils: Add toHex(), hexInvert(), hexLeftPad(), and hexRightPad() hex utils. 2019-09-04 20:15:15 -04:00
Lawrence Forman
7b5e3dab17 @0x/contracts-staking: Add rich reverts.
`@0x/utils`: Add `LibFixedMath` `RevertError` types.
`@0x/order-utils`: Add `InvalidCobbDouglasAlphaerror` `RevertError` type.
2019-09-04 20:15:15 -04:00
Lawrence Forman
a09cd03ce6 @0x/contracts-staking: Remove LibFeeMath and just put _cobbDouglas() in MixinExchangeFees.
`@0x/contracts-staking`: Update `LibFixedMath` to existing naming conventions.
`@0x/contracts-staking`: Add `cobbDouglasAlphaNumerator` and `cobbDouglasAlphaDenominator` to `Mixinstorage`.
`@0x/contracts-staking`: Add external `setCobbDouglasAlpha()` function to `MixinExchnageFees`
`@0x/contracts-staking`: Update `_cobbDouglas()` to use the new `LibFixedMath` voodoo.
`@0x/contracts-staking`: In reward calculations, use only delegated stake by pool owner as opposed to both delegated and active stake to compute stake totals.
2019-09-04 20:15:15 -04:00
Lawrence Forman
c1fc454d19 @0x/contracts-staking: Add uintMul() function to LibFixedMath. 2019-09-04 20:15:15 -04:00
Lawrence Forman
93c8284a96 @0x/contracts-staking: Add LibFeeMath library. 2019-09-04 20:15:15 -04:00
Amir Bandeali
e5dcf9063d Merge pull request #2127 from 0xProject/feat/3.0/catch-pay-protocol-fee-err
Wrap `payProtocolFee` with rich revert + reduce codesize
2019-09-04 13:51:19 -07:00
Amir Bandeali
cf35a8032d Update contracts/exchange/contracts/src/MixinProtocolFees.sol
Update comment

Co-Authored-By: James Towle <jalextowle@gmail.com>
2019-09-04 11:34:17 -07:00
Amir Bandeali
88736aa82b Merge pull request #2121 from 0xProject/feat/3.0/codesize
Reduce Exchange codesize
2019-09-03 21:08:50 -07:00
Amir Bandeali
90ac5ec577 Fix tests 2019-09-03 20:11:48 -07:00
Amir Bandeali
d1eb414749 Use new rich reverts where applicable 2019-09-03 20:11:47 -07:00
Amir Bandeali
f792d403e5 Add new rich revert errors 2019-09-03 20:11:47 -07:00
Amir Bandeali
e5706606a0 Create private functions for encoding orders/transactions with their hash to be passed into EIP1271 compliant contract 2019-09-03 20:11:43 -07:00
Amir Bandeali
49725c8c33 Styling and comment updates 2019-09-03 17:52:41 -07:00
Amir Bandeali
dfcc0c6d09 Create _enableAndRefundNonZeroBalance to slightly reduce codesize 2019-09-03 17:52:17 -07:00
Amir Bandeali
d806701d28 Use fromHex instead of doing length -> byte length calculation 2019-09-03 17:51:41 -07:00
Amir Bandeali
3935e661fe Add more writeLength tests 2019-09-03 17:05:32 -07:00
Amir Bandeali
cb8cf1f107 Add back batchFillOrders 2019-09-03 11:06:45 -07:00
Amir Bandeali
ea8669439f Minor styling and naming changes 2019-09-03 09:48:21 -07:00
Amir Bandeali
75a8b1c081 Use same taker numerator/denominator for all math in calculateFillResults 2019-09-03 09:48:16 -07:00
Amir Bandeali
73144fa4d5 Fix _setCurrentContextAddressIfRequired 2019-09-02 20:35:20 -07:00
Amir Bandeali
a6b60f3230 Create _readSignatureType with minimal validation 2019-09-02 20:34:23 -07:00
Amir Bandeali
48dfb3317a Fix tests 2019-09-02 14:36:27 -07:00
Amir Bandeali
b3b0496c49 Fix build and linting errors 2019-09-02 11:41:13 -07:00
Amir Bandeali
e880447714 Refactor EIP1271Wallet and Validator types to use new EIP1271SignatureError 2019-09-02 11:38:52 -07:00
Amir Bandeali
fd4d10e7a4 Create EIP1271SignatureError rich revert 2019-09-02 11:37:39 -07:00
Amir Bandeali
9974e10069 Fix Buffer warning 2019-09-01 19:14:28 -07:00
Amir Bandeali
18b65a61ff Fix build 2019-09-01 19:14:16 -07:00
Amir Bandeali
02a1e17f50 Reuse EIP1271 wallet code with internal function 2019-09-01 18:53:57 -07:00
Amir Bandeali
9a3a302754 Create writeLength function in LibBytes 2019-09-01 18:32:52 -07:00
Amir Bandeali
d131c39e46 Create _setCurrentContextAddressIfRequired function in MixinTransactions 2019-09-01 18:31:46 -07:00
Amir Bandeali
8231e7703e Allow unlimited contract sizes by default 2019-09-01 18:30:33 -07:00
Amir Bandeali
406a78a11a Use internal functions in Refundable modifiers 2019-09-01 17:43:18 -07:00
Amir Bandeali
fe01a150f0 Use internal function in onlyOwner, onlyAuthorized, and nonReentrant modifiers 2019-09-01 15:54:16 -07:00
Amir Bandeali
dd499591e9 Make assetProxies mapping internal (getter function already exists) 2019-09-01 15:13:57 -07:00
Amir Bandeali
c0f1e5f17f Make fillOrderNoThrow internal only, remove batchFillOrders 2019-09-01 12:22:00 -07:00
Amir Bandeali
b888e48a30 Remove getOrdersInfo 2019-09-01 11:24:16 -07:00
Amir Bandeali
8410ee9d2f Remove unnecessary public functions 2019-09-01 11:01:01 -07:00
Amir Bandeali
b7238c702b Increase optimizer runs 2019-09-01 11:00:07 -07:00
Amir Bandeali
a5996b37b2 Merge pull request #2116 from 0xProject/feat/3.0/eip1271-selectors
Add 4 byte ids to `EIP1271Wallet.isValidSignature` data
2019-08-30 13:38:25 -07:00
Amir Bandeali
b20503c5a2 Fix off by 1 error 2019-08-30 11:39:28 -07:00
Amir Bandeali
d0869a8840 Fix linting errors 2019-08-30 11:39:28 -07:00
Amir Bandeali
c156bfc534 Remove TestValidatorWallet DataType 2019-08-30 11:39:28 -07:00
Amir Bandeali
5f8e092c96 Move EIP1271 selectors to their own interface 2019-08-30 11:39:27 -07:00
Amir Bandeali
87c9f9af71 Remove example contracts 2019-08-30 11:37:40 -07:00
Amir Bandeali
65e5ecf49d Encode arguments with selector before passing into EIP1271 isValidSignature 2019-08-30 11:32:22 -07:00
James Towle
63f051a9d2 Merge pull request #2097 from 0xProject/feature/3.0/exchange/protocol-fees
Exchange Protocol Fees
2019-08-30 10:36:18 -07:00
Alex Towle
2c1393fb09 @0x:contracts-exchange Addressed lingering review comments 2019-08-29 23:50:48 -07:00
Alex Towle
dba0d8469d @0x:contracts-exchange Addressed review feedback 2019-08-29 15:20:52 -07:00
Alex Towle
75e6c45285 @0x:contracts-exchange Added the tests for getOrdersInfo back into the exchange 2019-08-28 17:02:43 -07:00
Alex Towle
e64e0d7421 @0x:contracts-exchange Added getOrdersInfo back into the exchange 2019-08-28 16:42:29 -07:00
Alex Towle
13d5a5e2ec @0x:contracts-exchange Added a test to ensure that registerAssetProxy will fail for non-contract proxies 2019-08-28 16:24:36 -07:00
Alex Towle
3432083343 @0x:contracts-staking Updated payProtocolFee trivially to fix the build.
This is not a real to update to `payProtocolFee`. Rather, the interface
was updated to it's finished state. This will be addressed in my next
PR.
2019-08-28 16:15:13 -07:00
Alex Towle
df4282fb34 Fixed issues after rebase 2019-08-28 15:50:23 -07:00
Alex Towle
861aebb2e3 @0x:contracts-exchange Refactored the protocol fee tests and added tests for batchFillOrders 2019-08-28 15:08:40 -07:00
Alex Towle
cc7b8359b4 @0x:contracts-exchange Added tests for matchOrders protocol fees 2019-08-28 15:05:33 -07:00
Alex Towle
dd0d848530 @0x:contracts-exchange Added tests for fillOrder protocol fees 2019-08-28 15:05:33 -07:00
Alex Towle
7f17033ce3 @0x:contracts-exchange Added protocol fees to fillOrders and matchOrders 2019-08-28 15:05:13 -07:00
Alex Towle
3a4e72bb08 @0x:contracts-exchange-libs Added protocol fees to LibFillResults
* This commit also squashed some bugs in the reference functions.
Thankfully, combinatorial testing had our back!
2019-08-28 15:03:32 -07:00
Alex Towle
bf3751fd9e @0x:contracts-exchange Added the MixinProtocolFees contract 2019-08-28 15:03:32 -07:00
Alex Towle
05eb646848 @0x:contracts-utils Added a Refundable contract 2019-08-28 15:01:30 -07:00
Amir Bandeali
5fe231b689 Reorder Cancel event args for consistency 2019-08-28 15:01:30 -07:00
Amir Bandeali
5ee7c2f9dc Reorder Fill event args to get around stack limit 2019-08-28 15:01:30 -07:00
Alex Towle
2c970a0466 @0x:contracts-exchange Added protocol fees to fill order 2019-08-28 15:01:30 -07:00
Alex Towle
c688b11c86 @0x:contracts-exchange-libs Added protocol fees to LibFillResults
* This commit also squashed some bugs in the reference functions.
Thankfully, combinatorial testing had our back!
2019-08-28 15:01:30 -07:00
Alex Towle
749c0354b3 @0x:contracts-staking Added protocol fee functions to IStaking 2019-08-28 14:56:40 -07:00
Alex Towle
415af90ae7 @0x:contracts-exchange Added the MixinStakingManager contract 2019-08-28 14:53:45 -07:00
Alex Towle
365cb161cf @0x:contracts-utils Added a Refundable contract 2019-08-28 14:51:57 -07:00
Amir Bandeali
a9857fa298 Merge pull request #2107 from 0xProject/feat/3.0/staking/remove-duplicate-code
Remove duplicate code from staking contracts
2019-08-28 14:30:37 -07:00
Amir Bandeali
59ae8d4b86 Fix comments in ZrxVault 2019-08-28 13:56:42 -07:00
Amir Bandeali
b81f6ba685 Fix linting error 2019-08-28 12:51:18 -07:00
Amir Bandeali
16c9d00494 Remove redundant function in MixinZrxVault 2019-08-28 11:20:00 -07:00
Amir Bandeali
1a833d9dfb Remove zrxAssetData param to ensure that it is always in sync with zrxToken 2019-08-28 11:06:46 -07:00
Amir Bandeali
bde6278781 Set 100 to PERGENTAGE_DENOMINATOR constant 2019-08-27 23:42:42 -07:00
Amir Bandeali
e7c4d2171f Update contracts to use 256 bit math 2019-08-27 23:42:42 -07:00
Amir Bandeali
3a096ff0b4 Remove 64 and 96 bit LibSafeMath contracts 2019-08-27 23:42:42 -07:00
Amir Bandeali
9feac6708a Add storage layout tests 2019-08-27 23:42:11 -07:00
Amir Bandeali
aabca97b2d Make most constants and storage vars uint256 2019-08-27 23:42:11 -07:00
Amir Bandeali
9fb933fd06 Remove MixinOwnable 2019-08-27 23:42:11 -07:00
Amir Bandeali
df039f05c2 Update contracts to use new SafeMath functions 2019-08-27 23:42:11 -07:00
Amir Bandeali
d1bed5729d Remove LibSafeMath and refactor 6/96 bit versions 2019-08-27 23:42:11 -07:00
mzhu25
c926a586d2 Merge pull request #2103 from 0xProject/feature/contracts-staking/rich-reverts
Staking RichErrors and cleanup
2019-08-26 17:32:05 -07:00
Amir Bandeali
b7397bbb8f Merge pull request #2101 from 0xProject/feat/3.0/cleanup
Revert to old ReentrancyGuard implementation + random cleanup
2019-08-26 17:14:17 -07:00
Michael Zhu
9b957524a5 replace abi.encodeWithSelector calls with bytes constant + other nits 2019-08-26 16:58:56 -07:00
Michael Zhu
078b1af04e Binop -> BinOp 2019-08-26 16:06:31 -07:00
Michael Zhu
6827ebfb78 blockchainTests.only -> blockchainTests 2019-08-26 15:58:31 -07:00
Michael Zhu
1d807abe8b lint 2019-08-26 15:49:09 -07:00
Michael Zhu
2c15b3f9bd remove staking RevertReasons from TS types, ExchangeAlreadyRegisteredError -> ExchangeAddressAlreadyRegisteredError 2019-08-26 15:49:09 -07:00
Michael Zhu
0d5e037081 use mocha extensions in staking tests 2019-08-26 15:49:09 -07:00
Michael Zhu
dbda3a04b2 update tests to use RichErrors 2019-08-26 15:49:09 -07:00
Michael Zhu
98e5b26eb7 refactor SafeMath rich errors and use them in staking libs 2019-08-26 15:49:09 -07:00
Michael Zhu
cd1fc6a1f0 fix typos 2019-08-26 15:49:09 -07:00
Michael Zhu
52ef745f7c run codegen script 2019-08-26 15:49:08 -07:00
Michael Zhu
961b09977f replace requires/reverts with rich errors 2019-08-26 15:49:08 -07:00
Amir Bandeali
df8419cd9e Add back comment on isReentrant function 2019-08-26 14:49:03 -07:00
Amir Bandeali
71acf2bfa7 Remove hard coded gas limits in all tests 2019-08-25 19:00:50 -07:00
Amir Bandeali
1400ceb4e8 Fix Exchange reentrancy tests 2019-08-25 18:29:04 -07:00
Amir Bandeali
793e338dd3 Revert to old ReentrancyGuard implementation 2019-08-25 17:06:52 -07:00
Amir Bandeali
020e7609c3 Add assetProxyId param to AssetProxyExistsError 2019-08-25 17:06:37 -07:00
Amir Bandeali
b1c2f66126 Update variable names in IAssetData 2019-08-25 16:51:37 -07:00
Amir Bandeali
8ef0a59b98 Merge pull request #2084 from 0xProject/feat/3.0/transactionGasPrice
Add `gasPrice` to 0x transactions
2019-08-24 10:13:07 -07:00
Amir Bandeali
798fb183a5 Address remaining PR feedback 2019-08-23 15:14:04 -07:00
Greg Hysz
6bb3992c2f Add files via upload
State transitions for stake.
2019-08-23 11:23:28 -07:00
Amir Bandeali
830d6f726e Use default gasPrice in Forwarder tests 2019-08-23 09:33:05 -07:00
Amir Bandeali
8f8c16bd0e Add more recursion tests 2019-08-23 09:25:09 -07:00
Amir Bandeali
76c0708cf2 Fix config.yml 2019-08-23 08:51:53 -07:00
Amir Bandeali
5e51233b49 Address PR feedback 2019-08-22 17:11:50 -07:00
Amir Bandeali
890bfd18fa Update tests to use new TransactionInvalidContextError 2019-08-22 17:04:15 -07:00
Amir Bandeali
37cc948741 Add TransactionInvalidContextError class 2019-08-22 17:04:15 -07:00
Amir Bandeali
edb923b8bb Use TransactionInvalidContextError in _assertExecutableTransaction 2019-08-22 17:04:15 -07:00
Amir Bandeali
44753bb168 Add TransactionInvalidContextError and remove NO_REENTRANCY errorCode 2019-08-22 17:04:15 -07:00
Amir Bandeali
7b96fa8d76 Add more unit tests 2019-08-22 17:04:15 -07:00
Amir Bandeali
ca35eed955 Add _assertExecutableTransaction unit tests 2019-08-22 17:04:15 -07:00
Amir Bandeali
eb6637afd5 Add public version of _assertExecutableTransaction 2019-08-22 17:04:15 -07:00
Amir Bandeali
a114bbb30e Reduce code duplication in unit tests 2019-08-22 17:04:15 -07:00
Amir Bandeali
9d38bf731f Add transaction gasPrice tests 2019-08-22 17:04:15 -07:00
Amir Bandeali
f32732db1c Add TransactionGasPriceError rich revert class 2019-08-22 17:04:15 -07:00
Amir Bandeali
f41a29ce55 Fix weth tests 2019-08-22 17:04:15 -07:00
Amir Bandeali
2b1e0be4fc Add default gasPrice to web3Wrapper instance and TransactionFactory 2019-08-22 17:04:15 -07:00
Amir Bandeali
23dd711396 Update ZeroExTransaction tests 2019-08-22 17:04:15 -07:00
Amir Bandeali
59369cea2a Update transaction hashing and tests 2019-08-22 17:04:14 -07:00
Amir Bandeali
e6b81a824d Update ZeroExTransaction schema 2019-08-22 17:04:14 -07:00
Amir Bandeali
1dd216b566 Update ZeroExTransaction interface 2019-08-22 17:04:14 -07:00
Amir Bandeali
27e2a76110 Update remaining contracts to use new transaction schema 2019-08-22 17:04:14 -07:00
Amir Bandeali
47da97137f Add _assertExecutableTransaction function and add gasPrice check 2019-08-22 17:04:14 -07:00
Amir Bandeali
2134537bc3 Add TransactionGasPriceError to LibExchangeRichErrors 2019-08-22 17:04:14 -07:00
Amir Bandeali
67f91269ee Add gasPrice to ZeroExTransaction struct 2019-08-22 17:04:14 -07:00
Alex Towle
57338059e1 CI: Split contracts tests up into two seperate jobs to attempt to increase speed 2019-08-22 17:04:14 -07:00
Alex Towle
c1ed836fda CI: Changed the test-contracts-ganache-3.0 to run in stages to avoid the Killed error 2019-08-22 17:03:15 -07:00
Alex Towle
cd147dbc41 @0x:contracts-exchange Fixed issues caused by rebase 2019-08-22 17:01:49 -07:00
Alex Towle
0253bba83b @0x:contracts-exchange Addressed review comments by completely overhauling transaction_unit_tests.ts 2019-08-22 17:01:49 -07:00
Alex Towle
d845b318b9 @0x:contracts-exchange Changed the signature validation stub function to not require state 2019-08-22 17:01:49 -07:00
Alex Towle
4b970905cf @0x:contracts-exchange Removed code written to transactions 2019-08-22 17:01:49 -07:00
Alex Towle
907771f084 @0x:contracts-exchange Added unit tests for batchExecuteTransactions 2019-08-22 17:01:49 -07:00
Alex Towle
1724ecd4c3 @0x:contracts-exchange Added unit tests for executeTransaction 2019-08-22 17:01:48 -07:00
Alex Towle
74b9ad5536 @0x:contracts-exchange Added unit tests for getCurrentContextAddress 2019-08-22 17:01:48 -07:00
mzhu25
4f1525fe27 Merge pull request #1987 from 0xProject/feature/contracts/3.0/remove-forwarder-fee-abstraction
Remove Forwarder fee abstraction and revamp tests
2019-08-22 10:55:10 -07:00
Michael Zhu
4dc7956b56 address greg's comments 2019-08-22 10:29:30 -07:00
mzhu25
453bf4d195 Merge pull request #2087 from 0xProject/fix/3.0/exchange/execute-noop-transfer
remove from != to check and update tests
2019-08-21 17:02:03 -07:00
Greg Hysz
249948e787 Merge pull request #1910 from 0xProject/feature/contracts-staking/first-implementation
[WIP] First Implementation of Staking Contracts (ZEIP 31)
2019-08-21 16:48:04 -07:00
Greg Hysen
c0acc8dfdf Fixed sorting in artifact generation 2019-08-21 16:30:35 -07:00
Michael Zhu
00e87864b1 remove from != to check and update tests 2019-08-21 13:07:59 -07:00
Greg Hysen
697e5df52d Added changelog entries and cleaned up merge 2019-08-21 13:05:11 -07:00
Greg Hysen
ba3cd454ba Fixed linter errors 2019-08-21 13:04:21 -07:00
Greg Hysen
de26925c13 Solidity 0.5.5 -> 0.5.9 2019-08-21 13:04:20 -07:00
Greg Hysen
47e00ff1a7 Renamed MixinTimelockedStake.sol -> MixinTimeLockedStake.sol 2019-08-21 13:04:20 -07:00
Greg Hysen
d106051ee3 CamelCase for timelocks 2019-08-21 13:04:20 -07:00
Greg Hysen
c939fe2287 moved natspec to above contract definition 2019-08-21 13:04:20 -07:00
Greg Hysen
41b372ffe6 Updates from staking PR review 2019-08-21 13:04:20 -07:00
Greg Hysen
5826825d11 Linter fixes 2019-08-21 13:04:20 -07:00
Greg Hysen
a765e47dca Got staking contracts working after rebase 2019-08-21 13:04:20 -07:00
Greg Hysen
de8b032df9 Removed the unused LibRewardsTest 2019-08-21 13:04:20 -07:00
Greg Hysz
f1b1eb3b58 Added contract registry to kill switch diagram 2019-08-21 13:04:20 -07:00
Greg Hysz
1f334d29ae New architecture images for README 2019-08-21 13:04:20 -07:00
Greg Hysz
3279d2a803 updated architecture descriptions 2019-08-21 13:04:19 -07:00
Greg Hysen
cd14d1ef0f ran prettier 2019-08-21 13:04:19 -07:00
Greg Hysen
9eb676fb46 Pinned contracts-multisig dependency on asset-proxy so it will build 2019-08-21 13:04:19 -07:00
Greg Hysen
6c82ebe956 Added more documentation to interfaces 2019-08-21 13:04:19 -07:00
Greg Hysen
3922d02910 Documented libraries and removed unnecessary interface, IMixinScheduler 2019-08-21 13:04:19 -07:00
Greg Hysen
6da70cfa0d Added top-level README to the staking package 2019-08-21 13:04:19 -07:00
Greg Hysen
15c8e06129 Ran contracts:gen 2019-08-21 13:04:19 -07:00
Greg Hysen
93506a4e27 Updated Epoch API for readability + documented Timelock Mixin 2019-08-21 13:04:19 -07:00
Greg Hysen
508e927d63 Removed unnecessary lib 2019-08-21 13:04:19 -07:00
Greg Hysen
ee969261b4 Documentation for MixinVaultCore 2019-08-21 13:04:19 -07:00
Greg Hysen
2a5742c12d Documentation + Events for ZrxVault 2019-08-21 13:04:19 -07:00
Greg Hysen
598d70c6dc Renamed getStakeDelegatedToPool -> getTotalStakeDelegatedToPool for readability 2019-08-21 13:04:19 -07:00
Greg Hysen
a49e47f34b Mixin Zrx Vault is ownable now 2019-08-21 13:04:19 -07:00
Greg Hysen
ad4d869137 Documentation for stake balances mixin 2019-08-21 13:04:19 -07:00
Greg Hysen
4ef86e6128 Adding documentation to delegated stake mixin 2019-08-21 13:04:18 -07:00
Greg Hysen
470036f6cb Working on new directory structure 2019-08-21 13:04:18 -07:00
Greg Hysen
835ab6ddd9 Fixed linearization issue - see https://github.com/hysz/SmartContractLinearizer ! 2019-08-21 13:04:18 -07:00
Greg Hysen
b0b387013c Moved timelock logic into its own contract 2019-08-21 13:04:18 -07:00
Greg Hysen
3e6cae0ca0 Documentation for MixinDelegatedStake 2019-08-21 13:04:18 -07:00
Greg Hysen
93844343de Documented MixinStake.sol 2019-08-21 13:04:18 -07:00
Greg Hysen
42430290d5 Split MixinStake into: MixinStake, MixinDelegatedStake and MixinTimelockedStake 2019-08-21 13:04:18 -07:00
Greg Hysen
ce15b4c678 Fixed linter errors 2019-08-21 13:04:18 -07:00
Greg Hysen
35f4e2fb4f Documented MixinStakingPoolRewardVault and StakingPoolRewardVault 2019-08-21 13:04:18 -07:00
Greg Hysen
501f6cbab9 Fixed linearization issue - see https://github.com/hysz/SmartContractLinearizer ! 2019-08-21 13:04:18 -07:00
Greg Hysen
a724dd98a9 Documented staking pool reward vault mixin 2019-08-21 13:04:18 -07:00
Greg Hysen
d5249425af Added documentation to MixinStakingPoolRewards 2019-08-21 13:04:18 -07:00
Greg Hysen
44c44a2b9c Some renaming pool -> staking pool for readability 2019-08-21 13:04:18 -07:00
Greg Hysen
eb1c48674a Condensed some functions in MixinStakingPools for readability 2019-08-21 13:04:17 -07:00
Greg Hysen
b44ab72557 Added introductory comment for staking pool rewards 2019-08-21 13:04:17 -07:00
Greg Hysen
e6a33dea0e Renamed xxxReward... to StakingPoolReward... 2019-08-21 13:04:17 -07:00
Greg Hysen
217811d0af added maker add/remove events to staking pools 2019-08-21 13:04:17 -07:00
Greg Hysen
ab3246cc71 Cleaned up staking pool mixin 2019-08-21 13:04:17 -07:00
Greg Hysen
829533d501 Renamed MixinFees -> MixinExchangeFees 2019-08-21 13:04:17 -07:00
Greg Hysen
8881118a15 Added event when ownership of contract changes 2019-08-21 13:04:17 -07:00
Greg Hysen
3f2be5b2da Documenting fees + rewards now use weighted stake in denominator of cobb douglas 2019-08-21 13:04:17 -07:00
Greg Hysen
9f1904ad3d Renamed MixinExchange to MixinExchangeManager and added documentation 2019-08-21 13:04:17 -07:00
Greg Hysen
09843c3cf1 Got staking contract building again 2019-08-21 13:04:17 -07:00
Greg Hysen
303279a766 Renamed MixinEpoch -> MixinScheduler 2019-08-21 13:04:17 -07:00
Greg Hysen
f560e7fa96 Renamed approval factory 2019-08-21 13:04:17 -07:00
Greg Hysen
c97c6d1fc2 LibSafeMath96Bit -> LibSafeMath96 2019-08-21 13:04:16 -07:00
Greg Hysen
b53bf051ac LibSafeMath64Bit -> LibSafeMath64 2019-08-21 13:04:16 -07:00
Greg Hysen
d5189e6143 linted contracts 2019-08-21 13:04:16 -07:00
Greg Hysen
a934c71ccd Fixing linter errors 2019-08-21 13:04:16 -07:00
Greg Hysen
5147b6e699 fixing linter errors 2019-08-21 13:04:16 -07:00
Greg Hysen
9294bf40a7 Ran yarn fix 2019-08-21 13:04:16 -07:00
Greg Hysen
a02f96c913 ran prettier 2019-08-21 13:04:16 -07:00
Greg Hysen
b756e723ea Updated dependency ordering using a linearizer script, which is now here: https://github.com/hysz/SmartContractLinearizer 2019-08-21 13:04:16 -07:00
Greg Hysen
8bc1d5fe3e Run all tests 2019-08-21 13:04:16 -07:00
Greg Hysen
180417b581 moved another test to the simulator 2019-08-21 13:04:16 -07:00
Greg Hysen
786655843b check reward balances of operator ocne withdarwn in simulator 2019-08-21 13:04:16 -07:00
Greg Hysen
5e3eeed10f more work on simulator 2019-08-21 13:04:16 -07:00
Greg Hysen
8a2df9cd1f Working on simulation to make it easier to follow the end-to-end tests. Mostly working. 2019-08-21 13:04:16 -07:00
Greg Hysen
74d9891e06 actors for maker / pool operator + comprehensive test cases 2019-08-21 13:04:16 -07:00
Greg Hysen
e0ff859e0d Separated test files out for readability 2019-08-21 13:04:15 -07:00
Greg Hysen
2c7efd0b97 separating out tests for readability 2019-08-21 13:04:15 -07:00
Greg Hysen
99a0835ecc Fixed staker actor assertions 2019-08-21 13:04:15 -07:00
Greg Hysen
0bb227a79b Delegator Actor 2019-08-21 13:04:15 -07:00
Greg Hysen
84e7357960 starting on a delegator actror 2019-08-21 13:04:15 -07:00
Greg Hysen
9d0b94305a deleted old staker test - much code saved! 2019-08-21 13:04:15 -07:00
Greg Hysen
8343105b54 cleaned up staker actor 2019-08-21 13:04:15 -07:00
Greg Hysen
38cad56bf9 Staker Actor 2019-08-21 13:04:15 -07:00
Greg Hysen
8f291c19c3 Use LibSafeMath in ZrxVault instead of util SafeMath 2019-08-21 13:04:15 -07:00
Greg Hysen
9566188d6b Renamed IVault to IZrxVault 2019-08-21 13:04:15 -07:00
Greg Hysen
cae8c2013d Split deployment constants into its own mixin for readability 2019-08-21 13:04:15 -07:00
Greg Hysen
9bc5efe958 Use safemath for epochs 2019-08-21 13:04:15 -07:00
Greg Hysen
b36003896f Renamed LibMath to LibFeeMath 2019-08-21 13:04:15 -07:00
Greg Hysen
4d2ba9f1e6 Replaced any contract-style libraries with real libraries. 2019-08-21 13:04:14 -07:00
Greg Hysen
56184c6f4f Removed Wrapper contracts. Too much sugar. Felt it was less readable. 2019-08-21 13:04:14 -07:00
Greg Hysen
1f64f9eae6 Other contracts packages building with LibEIP721 as a library (rather than a contract) 2019-08-21 13:04:14 -07:00
Greg Hysen
7aeeaae015 Getting other contract libraries to build with LibEIP712 now a regular library 2019-08-21 13:04:14 -07:00
Greg Hysen
03142d82bc added test for trying to put maker in pool when they havent signed the message properly 2019-08-21 13:04:14 -07:00
Greg Hysen
78805b1c39 Updated remaining tests to use maker signatures when adding to pool 2019-08-21 13:04:14 -07:00
Greg Hysen
e1a5ba9864 Pool Management test passing with signatures 2019-08-21 13:04:14 -07:00
Greg Hysen
bc0140ef3a Signature validation for adding makers to a staking pool 2019-08-21 13:04:14 -07:00
Greg Hysen
36b76550e0 Working towards maker signature validation 2019-08-21 13:04:14 -07:00
Greg Hysen
1f2e94b585 Adding signatures for maker acceptance into pool 2019-08-21 13:04:14 -07:00
Greg Hysen
e2a2f932f1 Created sepaerate mixins for interacting with the different vaults 2019-08-21 13:04:14 -07:00
Greg Hysen
6ca2f7e3ac Cleaned up staking contract with wrappers 2019-08-21 13:04:14 -07:00
Greg Hysen
f3309d3651 done tests 2019-08-21 13:04:14 -07:00
Greg Hysen
0b1d955a9f Added some more sanity checks for delegator reward balances 2019-08-21 13:04:13 -07:00
Greg Hysen
fb75fa4e9a Withdraw balances for rewards by operators 2019-08-21 13:04:13 -07:00
Greg Hysen
0ba8690120 Added functions for reward balances to staking API 2019-08-21 13:04:13 -07:00
Greg Hysen
cafa3c827c Updated naming on reward vault 2019-08-21 13:04:13 -07:00
Greg Hysen
bbacce2986 Removed operator from reward vault 2019-08-21 13:04:13 -07:00
Greg Hysen
ead2d26025 Test for delegator payouts when we use Shadow ETH 2019-08-21 13:04:13 -07:00
Greg Hysen
7d89449f2d Got delegation buy-in/payout test working 2019-08-21 13:04:13 -07:00
Greg Hysen
b3d1b6c499 Store separate operator / pool balances in the reward vault. This reduces complexity in the staking contract. 2019-08-21 13:04:13 -07:00
Greg Hysen
7d85e61cc5 Basic payouts to delegators when the pool is empty and they receive 100% of the reward. 2019-08-21 13:04:13 -07:00
Greg Hysen
362a8c8fc5 account for delegated stake when computing payouts. Tests pass 2019-08-21 13:04:13 -07:00
Greg Hysen
6041fb0445 finalizing payouts are correct 2019-08-21 13:04:13 -07:00
Greg Hysen
b2a7e0536e epoch finalization executes at about 25k gas / active maker 2019-08-21 13:04:13 -07:00
Greg Hysen
2d39454ce1 get logs when available, otherwise do not 2019-08-21 13:04:13 -07:00
Greg Hysen
16de8bf26c get logs with tx receipt 2019-08-21 13:04:13 -07:00
Greg Hysen
bb7cecd7c1 all tests passing again 2019-08-21 13:04:13 -07:00
Greg Hysen
8e41cc7651 Finalization with payouts compiles. 2019-08-21 13:04:12 -07:00
Greg Hysen
55238b9669 All tests are passing again. Minor fixes after messing around with different code 2019-08-21 13:04:12 -07:00
Greg Hysen
316ef69074 Adding some tests to the reward vault 2019-08-21 13:04:12 -07:00
Greg Hysen
8c839b5c22 Reward Vault Implementation with wrapper functions. Working on tests. 2019-08-21 13:04:12 -07:00
Greg Hysen
f98e1d75f4 Protocol fees only payable by a valid exchange 2019-08-21 13:04:12 -07:00
Greg Hysen
c57d17dc58 Exchange tracking 2019-08-21 13:04:12 -07:00
Greg Hysen
938f4d2d9d Protocol Fees implemented; some partially implemented code for other features in this commit,. 2019-08-21 13:04:12 -07:00
Greg Hysen
307c38bd16 payFee function 2019-08-21 13:04:12 -07:00
Greg Hysen
202dcfb4c5 Fixed a bug in the nth root that affects speed of computation. Also started playing with retaining decimal places of root computation 2019-08-21 13:04:12 -07:00
Greg Hysen
8dd74bcf82 test for delegating/undelegating 2019-08-21 13:04:12 -07:00
Greg Hysen
07acdc26ff starting a test for delegation 2019-08-21 13:04:12 -07:00
Greg Hysen
de307bf25a Moved constants and storage mixins to immutable directory 2019-08-21 13:04:12 -07:00
Greg Hysen
b6c4f533d2 completed staking test 2019-08-21 13:04:12 -07:00
Greg Hysen
cbf41e6ade Minor bug fixes in staking + tests making progress 2019-08-21 13:04:11 -07:00
Greg Hysen
b1d98a4183 Updated tests for epochs. More robust and helpful for staking tests. 2019-08-21 13:04:11 -07:00
Greg Hysen
30db88d27b test case for epoch management 2019-08-21 13:04:11 -07:00
Greg Hysen
fc9d5dee5e updated wrapper with epoch management 2019-08-21 13:04:11 -07:00
Greg Hysen
bb0ada3f59 adding epoch management 2019-08-21 13:04:11 -07:00
Greg Hysen
804256075e added new staking/delegating/timelock functions to staking wrapper 2019-08-21 13:04:11 -07:00
Greg Hysen
79f28f121b checkpoint - implementing delegating + timelocks 2019-08-21 13:04:11 -07:00
Greg Hysen
717a19a08e moving towards working delegation + timelocks. 2019-08-21 13:04:11 -07:00
Greg Hysen
9c8716da09 delegating logic 2019-08-21 13:04:11 -07:00
Greg Hysen
8293784629 tests for pool management 2019-08-21 13:04:11 -07:00
Greg Hysen
a17f123608 Added ABI decoding of return values to callAsync 2019-08-21 13:04:11 -07:00
Greg Hysen
561fe9c3ea tests for pools - create pool and increment id 2019-08-21 13:04:11 -07:00
Greg Hysen
e645aa1ee5 some methods only callable by pool operator 2019-08-21 13:04:11 -07:00
Greg Hysen
7f86d2c5fa Renamed "Maker Ids" to "Pools" 2019-08-21 13:04:11 -07:00
Greg Hysen
fae14a755f maker registry compiles, untested 2019-08-21 13:04:11 -07:00
Greg Hysen
1c14948f8a Saved 20k gas on cobb douglas computation w binary search 2019-08-21 13:04:10 -07:00
Greg Hysen
6a902eff56 Split Storage Logic + Staking Logic Contracts 2019-08-21 13:04:10 -07:00
Greg Hysen
c6192ea953 adding events for staking 2019-08-21 13:04:10 -07:00
Greg Hysen
36cf4ad304 some refactoring for the staking proxy. Compiles, but no tests yet. 2019-08-21 13:04:10 -07:00
Greg Hysen
bcfabf18bc cobb douglas / simplified / inverse simplified (better results across the board - esp w simplified impls) 2019-08-21 13:04:10 -07:00
Greg Hysen
f15693af1d Much simplified cobb douglas implementation 2019-08-21 13:04:10 -07:00
Greg Hysen
64e42d18e2 works for square roots 2019-08-21 13:04:10 -07:00
Greg Hysen
e2a76c621b working on it 2019-08-21 13:04:10 -07:00
Greg Hysen
19f6a8dcfe decent cobb douglas implementation 2019-08-21 13:04:10 -07:00
Greg Hysen
3c4cfe8aee fixed point nth root. This is what well use for the cobb-douglas function when computing rewards. 2019-08-21 13:04:10 -07:00
Greg Hysen
43173c1aac Run Newtons nth root algorithm after approximating the root 2019-08-21 13:04:10 -07:00
Greg Hysen
95b284d648 Function to compute nth root 2019-08-21 13:04:10 -07:00
Greg Hysen
9787cf8296 hooked up interface to MixinStake 2019-08-21 13:04:10 -07:00
Greg Hysen
93b57445b6 unstaking works 2019-08-21 13:04:10 -07:00
Greg Hysen
c4ca72cf22 staking end-to-end works 2019-08-21 13:04:10 -07:00
Greg Hysen
13d2cca2bc staking looks good, aside from the xfer of zrx 2019-08-21 13:04:10 -07:00
Greg Hysen
7fe8eac511 compiles and deploys 2019-08-21 13:04:10 -07:00
Greg Hysen
c062458188 Writing staking tests 2019-08-21 13:04:09 -07:00
Greg Hysen
3517dd2741 Implemented staking logic and ZRX vault 2019-08-21 13:04:09 -07:00
Lawrence Forman
7407890deb Merge pull request #2075 from 0xProject/feature/3.0/exchange/market-fill-or-kill
Add marketBuy/SellOrdersFillOrKill() to Exchange
2019-08-21 11:24:24 -04:00
Lawrence Forman
e9a4b0758b @0x/contracts-exchange: Remove log decoding in ExchangeWrapper test class in favor of awaitTransactionSuccessAsync. 2019-08-21 10:59:34 -04:00
Lawrence Forman
abf076fc05 @0x/contracts-exchange: Remove unused _getOrderHashes() function from MixinWrapperFUnctions. 2019-08-21 10:59:34 -04:00
Lawrence Forman
c344625d0d @0x/utils: Ran prettier. 2019-08-21 10:59:34 -04:00
Lawrence Forman
14630465dd @0x/order-utils: Add comments to regex parsing code in revert_error.ts. 2019-08-21 10:59:34 -04:00
Lawrence Forman
a497ddfad2 @0x/contracts-exchange: Update CHANGELOG and run prettier. 2019-08-21 10:59:34 -04:00
Lawrence Forman
34f6facdee @0x/contracts-exchange-libs: Update CHANGELOG. 2019-08-21 10:59:34 -04:00
Lawrence Forman
c3bff31cc4 @0x/order-utils: Update CHANGELOG and run prettier. 2019-08-21 10:59:34 -04:00
Lawrence Forman
e4475c08e8 @0x/contracts-exchange: Switch to consolidated IncompleteFillError rich error.
`@0x/contracts-exchange`: Allow `marketSell/BuyOrdersNoThrow` to be destructive to orders again.
2019-08-21 10:59:34 -04:00
Lawrence Forman
75a4d129f7 @0x/contracts-exchange-libs: Consolidate FillOrKill errors into IncompleteFillError. 2019-08-21 10:59:34 -04:00
Lawrence Forman
c659477358 @0x/order-utils: Consolidate FillOrKill errors into IncompleteFillError. 2019-08-21 10:59:34 -04:00
Lawrence Forman
43f38d02ad @0x/contracts-dev-utils: run_mocha package script runs with UNLIMITED_CONTRACT_SIZE=true environment variable. 2019-08-21 10:59:34 -04:00
Lawrence Forman
6b8bc55c74 @0x/contracts-test-utils: web3Wrapper is created with shouldAllowUnlimitedContractSize if UNLIMITED_CONTRACT_SIZE environment variable is set. 2019-08-21 10:59:34 -04:00
Lawrence Forman
0c53e2fe46 @0x/dev-utils: Make ganache's allowUnlimitedCOntractSize option configurable via Web3Config.
`@0x/dev-utils`: Add `UnlimitedContractSize` to `EnvVars`.
2019-08-21 10:59:34 -04:00
Lawrence Forman
edef3bc30e @0x/contracts-exchange: Fix failing wrapper.ts test. 2019-08-21 10:59:34 -04:00
Lawrence Forman
0c7f09b832 ran prettier 2019-08-21 10:59:34 -04:00
Lawrence Forman
34d075ce8c @0x/contracts-exchange: Update marketBuy/SellOrdersNoThrow() to NOT be destructive to the orders.
`@0x/contracts-exchange`: Fix wrapper unit tests to use the actual order hash algorithm, since it can't be overridden anymore.
2019-08-21 10:59:34 -04:00
Lawrence Forman
8c06d660ea Update CHANGELOGs with PR numbers. 2019-08-21 10:59:34 -04:00
Lawrence Forman
748566b4fb @0x/contracts-exchange: Tweak exchangeDataEncoder test utility to work with marketBuy/SellFillOrKill() functions. 2019-08-21 10:59:34 -04:00
Lawrence Forman
fb38867e78 Ran prettier 2019-08-21 10:59:34 -04:00
Lawrence Forman
a2613625c6 @0x/contracts-exchange: Squelch linter errors in LibExchangeRichErrorDecoder. 2019-08-21 10:59:34 -04:00
Lawrence Forman
89f1d54ebc @0x/contracts-dev-utils: Add marketBuy/SellOrdersNoThrow and marketBuy/SellOrdersFillOrKill to LibTransactionDecoder. 2019-08-21 10:59:34 -04:00
Lawrence Forman
740913fa20 @0x/dev-utils: Set allowUnlimitedContractSize option when creating a ganache provider. 2019-08-21 10:59:34 -04:00
Lawrence Forman
fd2a240c9f @0x/contracts-exchange`: Update changelog. 2019-08-21 10:59:34 -04:00
Lawrence Forman
96bef08ac2 @0x/contracts-exchange: Rename marketSellOrders and marketBuyOrders back to marketSellOrdersNoThrow and marketBuyOrdersNoThrow.
`@0x/contracts-exchange`: Introduce new `marketSellOrdersFillOrKill` and `marketBuyOrdersFillOrKill` functions.
`@0x/contracts-exchange`: Add new rich error types: `IncompleteMarketBuyError` and `IncompleteMarketSellError`.
`@0x/contracts-exchange`: Use `abi.decode()` in `LibExchangeRichErrorDecoder` over `LibBytes`.
2019-08-21 10:59:34 -04:00
Lawrence Forman
1698519a6a @0x/contracts-exchange: Overridden functions in ReentrancyTester now return sane values. 2019-08-21 10:59:34 -04:00
Lawrence Forman
d8372f73bc @0x/contracts-exchange-libs: Add new revert types and use abi.decode() instead of LibBytes. 2019-08-21 10:59:34 -04:00
Lawrence Forman
fb6e8a4608 @0x/order-utils: Add takerAssetFillAmount field to IncompleteFillError type.
`@0x/order-utils`: Add `IncompleteMarketSellError` and `IncompleteMarketBuyError` `RevertError` types.
2019-08-21 10:59:34 -04:00
Lawrence Forman
a3f6160898 @0x/utils: Allow for array types in RevertError types. 2019-08-21 10:59:34 -04:00
Michael Zhu
66f175b659 post-rebase fix 2019-08-20 17:41:26 -07:00
Michael Zhu
755ef35955 prettier 2019-08-20 17:24:59 -07:00
Michael Zhu
b5d6156ffa use mocha extensions 2019-08-20 17:24:59 -07:00
Michael Zhu
8dd8cf8673 might as well change ethValueAdjustment to number too 2019-08-20 17:24:59 -07:00
Michael Zhu
9e46099ced change fractionalNumberOfOrdersToFill to number 2019-08-20 17:24:59 -07:00
Michael Zhu
9f4fe259f9 update some RichErrors and @return directives per comments 2019-08-20 17:24:59 -07:00
Michael Zhu
3c169388e2 refactor + address comments on forwarder mixins 2019-08-20 17:24:59 -07:00
Michael Zhu
b9e75769a3 add tests for partially filled, unfillable orders 2019-08-20 17:24:59 -07:00
Michael Zhu
17a9edd8c3 check order statuses 2019-08-20 17:24:59 -07:00
Michael Zhu
090b83a237 tests for invalid fee assets 2019-08-20 17:24:59 -07:00
Michael Zhu
7796c88be3 add forwarder back to contractsPackages 2019-08-20 17:24:59 -07:00
Michael Zhu
e5ee794895 slipped through from a previous commit 2019-08-20 17:24:59 -07:00
Michael Zhu
2b572cc28f fix lint 2019-08-20 17:24:59 -07:00
Michael Zhu
88544ae0ef fix dependencies 2019-08-20 17:24:59 -07:00
Michael Zhu
146d56be84 use new lib function names 2019-08-20 17:24:59 -07:00
Michael Zhu
1934dddcbe use different maker/taker amounts in tests 2019-08-20 17:24:59 -07:00
Michael Zhu
f1c51bd0db refactor + revert when takerFeeAssetData is neither WETH nor makerAssetData 2019-08-20 17:24:59 -07:00
Michael Zhu
d91fc59a28 change marketSell/marketBuy to return relevant amounts, change marketBuy so that makerAssetBuyAmount == makerAssetAcquiredAmount 2019-08-20 17:24:59 -07:00
Michael Zhu
f8025feda2 update tests to use RevertErrors 2019-08-20 17:24:58 -07:00
Michael Zhu
c9f0c46017 forwarder rich errors second pass 2019-08-20 17:24:58 -07:00
Michael Zhu
5879aeac52 forwarder rich errors first pass 2019-08-20 17:24:58 -07:00
Michael Zhu
c73ae579d3 rebase + fix CI 2019-08-20 17:23:55 -07:00
Michael Zhu
3da55ad836 lint 2019-08-20 17:23:55 -07:00
Michael Zhu
26bfcccedc use ForwarderTestFactory for most forwarder tests + some comments in forwarder_test_factory 2019-08-20 17:23:55 -07:00
Michael Zhu
af6243afb0 handle reverts and ERC721 in ForwarderTestFactory + refactoring 2019-08-20 17:23:55 -07:00
Michael Zhu
673a341626 make approveMakerAssetProxy an external function and update comments 2019-08-20 17:23:55 -07:00
Michael Zhu
a1aee7111a minor fixes 2019-08-20 17:23:55 -07:00
Michael Zhu
688209e272 refactoring and marketBuyTestAsync 2019-08-20 17:23:55 -07:00
Michael Zhu
116945047b forwarder test factory first pass (supports orders with no fees and percentage fees) 2019-08-20 17:23:55 -07:00
Michael Zhu
1b8a9e16e2 slightly restructure contracts to fix bug in the WETH-fee case 2019-08-20 17:23:55 -07:00
Michael Zhu
7ff7e9d2e7 Tests for orders without fees, orders with percentage-based fees (no forwarder fees) 2019-08-20 17:23:55 -07:00
Michael Zhu
15c0d622c9 Update function definitions, require that makerAsset is the same across orders, approve proxy to transfer makerAsset (for percentage-based fees) 2019-08-20 17:23:55 -07:00
Michael Zhu
25087f3c92 Remove fee abstraction from Forwarder contracts (first pass) 2019-08-20 17:23:55 -07:00
Michael Zhu
34be9830af fix imports and inheritance, update tests for forwarder 2019-08-20 17:23:55 -07:00
Amir Bandeali
0fad6a6ec1 Merge pull request #2076 from 0xProject/feat/3.0/truffle-config
Add truffle config file, update copyright dates
2019-08-20 15:12:26 -07:00
Amir Bandeali
02599c0df8 Add truffle artifacts to prettierignore 2019-08-20 14:30:29 -07:00
Amir Bandeali
430d068d78 Add truffle compile to build in CI 2019-08-20 12:57:31 -07:00
Amir Bandeali
f09cadb7b3 Add truffle compile option to contract packages 2019-08-20 12:49:33 -07:00
Amir Bandeali
c366a4bd83 Update copyright dates 2019-08-20 12:49:01 -07:00
Alex Towle
22c8a25a26 Merge branch 'development' into 3.0 2019-08-19 11:13:21 -07:00
Amir Bandeali
4c78b7d4bb Merge pull request #2055 from 0xProject/feat/3.0/optimizeConstants
Refactor library usage
2019-08-16 07:40:54 -07:00
Amir Bandeali
8402d211bf Update CHANGELOGs 2019-08-15 16:51:50 -07:00
Amir Bandeali
cc3be9448a Move MatchedFillResults constants closer to tests where they are utilized 2019-08-15 16:51:40 -07:00
Amir Bandeali
7ac30c5153 Merge branch '3.0' into feat/3.0/optimizeConstants 2019-08-15 15:20:48 -07:00
Greg Hysz
64bc99101c Merge pull request #2059 from 0xProject/feature/contracts/3.0/fillOrderAssertionWrapper
Fill Order Assertion Wrapper
2019-08-15 00:12:40 +02:00
Greg Hysen
09b5018e65 Readability improvements 2019-08-14 23:45:07 +02:00
Amir Bandeali
1dae1d244c Rename hashing functions in LibOrder and LibZeroExTransaction 2019-08-14 13:38:12 -07:00
Amir Bandeali
2da996f493 Hard code chainId in tests 2019-08-14 11:07:28 -07:00
Amir Bandeali
c5d4559300 Remove generate-exchange-selectors script 2019-08-14 11:07:22 -07:00
James Towle
434d027133 Merge pull request #2043 from jalextowle/feature/contracts/3.0/order-matching-unit-tests
MatchOrders Unit Tests
2019-08-14 11:06:52 -07:00
James Towle
f66212ce23 Merge pull request #2051 from jalextowle/feature/3.0/exchange-libs/unit-tests
`@0x:contracts-exchange-libs` Added unit tests to exchange-libs
2019-08-14 10:52:10 -07:00
Alex Towle
6b4e632101 @0x:contracts-exchange Refactored internal.ts so that it is more readable 2019-08-14 10:39:36 -07:00
Alex Towle
0134b2874b @0x:contracts-exchange Addressed remaining review comments 2019-08-13 17:05:38 -07:00
Alex Towle
e2308aabed @0x:contracts-exchange Reduced the code size of internal.ts 2019-08-13 17:04:42 -07:00
Alex Towle
36fac3532c Removed unused reference functions 2019-08-13 17:04:42 -07:00
Alex Towle
327c6e8ac2 Completed the calculateMatchedFillResultsWithMaximalFill tests 2019-08-13 17:04:25 -07:00
Alex Towle
e9d49d96a6 Changed the testing style to be more assertion based rather than reference based to leverage the fixtures from the integration tests 2019-08-13 17:04:25 -07:00
Alex Towle
929bb86a54 Wrote some test cases for assertValidMatch 2019-08-13 17:04:25 -07:00
Alex Towle
f58e28d1be Implemented reference functions and added tests for _calculateCompleteRightFill 2019-08-13 17:04:25 -07:00
Alex Towle
cdabe21e7a Fixed the tests by using the IsolatedExchange 2019-08-13 17:04:25 -07:00
Alex Towle
a7520eeaa8 Wrote some initial test cases for the matchOrders calculate functions 2019-08-13 17:02:00 -07:00
Amir Bandeali
070147db52 Fix build errors 2019-08-13 16:43:55 -07:00
Amir Bandeali
55436510b6 Regenerate boilerplate for exchange-libs package 2019-08-13 16:20:35 -07:00
Amir Bandeali
1aec5e455d Remove coordinator from CI tests 2019-08-13 16:20:35 -07:00
Amir Bandeali
dc31294440 Move LibExchangeRichErrors to exchange-libs package 2019-08-13 16:20:35 -07:00
Amir Bandeali
d3b8070fd6 Fix TestValidatorWallet by using new LibOrder and LibZeroExTransaction hashing 2019-08-13 16:19:48 -07:00
Amir Bandeali
26e4d66163 Remove unimplemented functions from interface 2019-08-13 16:19:48 -07:00
Amir Bandeali
7cfceebeb8 Remove unused ABIEncoderV2 pragma 2019-08-13 16:19:48 -07:00
Amir Bandeali
0e2616f16b Rename _rrevert to rrevert 2019-08-13 16:19:48 -07:00
Amir Bandeali
ccce7e001e Compile all contracts by default, regenerate boilerplate 2019-08-13 16:19:48 -07:00
Amir Bandeali
e91ba07f14 Do not overwrite all contracts identifier in compiler.json 2019-08-13 16:11:57 -07:00
Amir Bandeali
fb7b51d91b Get contracts list from Compiler class to add support for reading all contracts by default 2019-08-13 16:11:57 -07:00
Amir Bandeali
88d055c3db Make function public method of Compiler class 2019-08-13 16:11:57 -07:00
Amir Bandeali
3afce213c0 Add rrevert to safeDiv in LibSafeMath 2019-08-13 16:11:57 -07:00
Amir Bandeali
45f229c531 Move LibEIP712ExchangeDomain tests to own file 2019-08-13 16:11:57 -07:00
Amir Bandeali
d6772b4a0a Fix linting errors 2019-08-13 16:11:57 -07:00
Amir Bandeali
5016d50c2b Move calculateFillResults tests to exchange-libs package 2019-08-13 16:11:09 -07:00
Amir Bandeali
24eaf93db8 Move all exchange-libs tests to separate files 2019-08-13 16:11:09 -07:00
Amir Bandeali
2e519b534d Fix build in OrderValidationUtils 2019-08-13 16:11:09 -07:00
Amir Bandeali
31c2b36039 Fix build errors in exchange package contracts 2019-08-13 16:11:09 -07:00
Amir Bandeali
245956c658 Create test contracts for each exchange lib 2019-08-13 16:11:09 -07:00
Amir Bandeali
0df360c5e8 Fix compile errors 2019-08-13 16:11:09 -07:00
Amir Bandeali
9b786df828 Update test contracts 2019-08-13 16:11:09 -07:00
Amir Bandeali
ae859fa01e Update Exchange contract to use libraries 2019-08-13 16:11:09 -07:00
Amir Bandeali
7eb64eb3dc Update test contracts 2019-08-13 16:09:48 -07:00
Amir Bandeali
f45014f75b Convert LibOrder and LibZeroExTransaction to libraries 2019-08-13 16:09:48 -07:00
Amir Bandeali
74a5c8c23c Simplify LibEIP712ExchangeDomain to be used only for generating domain hash 2019-08-13 16:09:48 -07:00
Amir Bandeali
28e781db15 Convert LibFillResults to library 2019-08-13 16:09:48 -07:00
Amir Bandeali
6ca9d4ee78 Convert LibMath to library 2019-08-13 16:09:48 -07:00
Amir Bandeali
52dcd998c4 Add library implementation of SafeMath 2019-08-13 16:09:48 -07:00
Amir Bandeali
a8cd168345 Cleanup imports 2019-08-13 16:09:48 -07:00
Amir Bandeali
b05a2a90d0 Move FillResults calculations into LibFillResults 2019-08-13 16:09:48 -07:00
Amir Bandeali
242715240b Do not inherit libs 2019-08-13 16:07:07 -07:00
Amir Bandeali
65f17fd76e Make LibEIP712 a library 2019-08-13 16:04:33 -07:00
Amir Bandeali
58ee4447a1 Remove remaining hard coded selectors 2019-08-13 16:04:33 -07:00
Amir Bandeali
d153ac0951 Make remaining functions public 2019-08-13 16:04:33 -07:00
Amir Bandeali
2e97cfa5e5 Remove LibAssetProxyIds and TestLibConstants 2019-08-13 16:04:33 -07:00
Amir Bandeali
7d5276ad11 Remove LibExchangeSelectors.sol 2019-08-13 16:04:33 -07:00
Amir Bandeali
2251e5e418 Optimize LibEIP712 2019-08-13 16:00:19 -07:00
Alex Towle
e4257fb6c7 Addressed review comments and prettified code 2019-08-13 11:06:41 -07:00
Lawrence Forman
f22b03fdb5 Merge pull request #2042 from 0xProject/feature/3.0/exchange/wrapper-tests
Wrapper/Reentrancy unit tests, etc.
2019-08-13 13:55:29 -04:00
Greg Hysen
dd4541c825 Fill Order Assertion Wrapper 2019-08-13 17:51:40 +02:00
Lawrence Forman
98f77394ed @0x/contracts-dev-utils: Update OrderValidationUtils for new isValidOrderSignature() semantics. 2019-08-12 19:18:57 -04:00
Lawrence Forman
fc18db10be @0x/contracts-exchange: Add tests for when callback signature types return incorrect data. 2019-08-12 19:10:24 -04:00
Lawrence Forman
9382e2e8c7 @0x/contracts-exchange: Fix bad resultData assertion in fillOrderNoThrow(). 2019-08-12 18:53:40 -04:00
Lawrence Forman
a3b2dbf8e2 @0x/contracts-exchange: Remove redundant new bytes(0) in ReentrancyTester.sol. 2019-08-12 18:32:05 -04:00
Lawrence Forman
6df190edbb @0x/contracts-exchange: Light changes to address PR comments. 2019-08-12 18:20:50 -04:00
Lawrence Forman
5b0b8a9717 @0x/contracts-exchange: Remove explicit signerAddress parameter from many MixinSignatureValidator functions. 2019-08-12 18:10:57 -04:00
Lawrence Forman
a8ddbe4127 @0x/contracts-exchange: Update IWallet for new legacy wallet spec. 2019-08-12 17:30:24 -04:00
James Towle
6e1fdda182 Update contracts/exchange-libs/test/lib_zero_ex_transaction.ts
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-08-12 11:06:01 -07:00
Lawrence Forman
ca33090793 @0x/contracts-exchange: Add comments to LEGACY_WALLET_MAGIC_VALUE constant in TestValidatorWallet.sol.
`@0x/contracts-exchange`: Remove references to `LibExchangeSelectors` in the Exchange.
2019-08-09 22:15:33 -04:00
Lawrence Forman
e34b390c18 @0x/contracts-exchange-libs: Fix CHANGELOG rebase issues. 2019-08-09 22:15:33 -04:00
Lawrence Forman
370df0d495 @0x/contracts-dev-utils: Prettier.
`@0x/contracts-exchange`: Update reentrancy tests.
`@0x/contracts-exchange`: Add all mutator functions to
`ExchangeFunctions` type.
`@0x/contracts-tes-utils`: Remove unused import.
2019-08-09 22:15:33 -04:00
Lawrence Forman
d4e300d0a4 @0x/contracts-dev-util: Remove references to marketXOrdersNoThrow.
`@0x/contracts-exchange`: Remove references to `marketXOrdersNoThrow`.
2019-08-09 22:15:33 -04:00
Lawrence Forman
c83864af9c @0x/contracts-exchange: Fix broken tests.
`@0x/contracts-test-utils`: Remove unecessary wait timeout in
`LogDecoder`.
2019-08-09 22:15:33 -04:00
Lawrence Forman
14fe3045dc @0x/contracts-exchange-libs: Update CHANGELOG. 2019-08-09 22:15:33 -04:00
Lawrence Forman
5d54e6c951 @0x/contracts-dev-utils: Remove references to 'NoThrow' variants of
`MarketXOrders' functions.
2019-08-09 22:15:33 -04:00
Lawrence Forman
921e78c9e2 Update changelogs 2019-08-09 22:15:33 -04:00
Lawrence Forman
b1778825cb @0x/contracts-exchange: Remove ReentrantERC20Token from compiler
config.
2019-08-09 22:15:33 -04:00
Lawrence Forman
cc8d5ac93a Update changelogs. 2019-08-09 22:15:33 -04:00
Lawrence Forman
1d0dce7366 @0x/contracts-coordinator: Update for marketXOrders name change.
`@0x/contracts-coordinator`: Add `MixinCoordinatorApprovalVerifier.sol` to `.solhintignore` because of `abi.decode` issues.
2019-08-09 22:15:33 -04:00
Lawrence Forman
ae454b0892 @0x/contracts-exchange-libs: Regenerate selectors. 2019-08-09 22:15:33 -04:00
Lawrence Forman
a2234b745c @0x/contracts-exchange: Create semi-automated reentrancy testing.
`@0x/contracts-exchange`: Remove old reentrancy tests.
`@0x/contracts-exchange`: Remove `ReentrantERC20Token` contract.
2019-08-09 22:15:33 -04:00
Lawrence Forman
3dd8dac146 @0x/contracts-exchange: Update Wallet signature type behavior to match v2.1.
`@0x/contracts-exchange`: Add EOA tests to `signature_validator`.
2019-08-09 22:15:33 -04:00
Lawrence Forman
6752fc9fe5 @0x/order-utils: Add ExchangeRevertErrors.SignatureErrorCode.InvalidSigner. 2019-08-09 22:15:33 -04:00
Lawrence Forman
0d05411cd2 @0x/contracts-exchange: Update CHANGELOG, lint, prettify. 2019-08-09 22:15:33 -04:00
Lawrence Forman
7ce65e3cfe @0x/contracts-exchange: Wrap up tests in wrapper_unit_tests. 2019-08-09 22:15:33 -04:00
Lawrence Forman
ea1501abd1 @0x/contracts-exchange: Change how order hashes and signatures are computed for wrapper_unit_tests. 2019-08-09 22:15:33 -04:00
Lawrence Forman
ca28b8f93e @0x/contracts-exchange: Make marketBuy/SellNoThrow the default.
`@0x/contracts-exchange`: Add more `wrapper_unit_tests` tests.
2019-08-09 22:15:33 -04:00
Lawrence Forman
566e74310a @0x/contracts-exchange: Remove assembly from fillOrderNoThrow(). 2019-08-09 22:15:33 -04:00
Lawrence Forman
c18e8ba242 @0x/contracts-exchange: Add more tests to wrapper_unit_tests. 2019-08-09 22:15:33 -04:00
Lawrence Forman
1f3f0dce11 @0x/contracts-exchange: Add fillOrderNoThrow tests to wrapper_unit_tests. 2019-08-09 22:15:33 -04:00
Lawrence Forman
b73008d83d @0x/contracts-exchange: Fix fillOrKillOrder() tests in wrapper_unit_tests. 2019-08-09 22:15:33 -04:00
Lawrence Forman
10a8291391 @0x/contracts-exchange: Add more tests to wrapper_unit_tests. 2019-08-09 22:15:33 -04:00
Lawrence Forman
ab094ab174 @0x/contracts-exchange: Add more tests to wrapper_unit_tests. 2019-08-09 22:15:33 -04:00
Lawrence Forman
29a82f8471 @0x/contracts: Create TestWrapperFunctions contract. 2019-08-09 22:15:33 -04:00
Lawrence Forman
8adfa52ae3 Merge branch 'feature/3.0/exchange/fill-order-unit-tests' into 3.0 2019-08-09 22:06:32 -04:00
Lawrence Forman
18485dd456 @0x/contracts-exchange-libs: Add complementary tests when rounding up and down behavior with isRoundingErrorFloor() and isRoundingerrorCeil(). 2019-08-09 21:07:23 -04:00
Alex Towle
c318b849fe @0x:contracts-exchange-libs Added unit tests to exchange-libs 2019-08-09 17:28:36 -07:00
Lawrence Forman
e3aa76cd09 @0x/contracts-exchange: Light refactoring in
`isolated_fill_order.ts` and `isolated_exchange_wrapper.ts`.
2019-08-08 11:43:55 -04:00
Lawrence Forman
de897d2ebf @0x/contracts-test-utils: Refactor LogDecoder slightly. 2019-08-08 11:43:20 -04:00
Lawrence Forman
08118ec36f @0x/contracts-exchange-libs: Fix coverage hooks.
`@0x/contracts-exchange-libs`: Add explicit tests for
`*getPartialAmount*()` for rounding modes.
2019-08-08 11:41:51 -04:00
Amir Bandeali
f757a9de52 Add devdoc comments to IAssetData 2019-08-06 15:51:59 -07:00
Lawrence Forman
6d502b6898 @0x/contracts-exchange: Use TransactionHelper to call and execute
contract functions.
2019-08-06 15:31:30 -04:00
Lawrence Forman
0eff19f0ff @0x/contracts-test-utils: Add TransactionHelper class.
`@0x/contracts-test-utils`: Add `decodeReceiptLogs()` to `LogDecoder`
class.
2019-08-06 15:31:30 -04:00
Lawrence Forman
b6dfc791d4 @0x/contracts-exchange: Correct test case name. 2019-08-06 15:31:30 -04:00
Lawrence Forman
7002dc63bd @0x/contracts-exchange: Fix typos in comments. 2019-08-06 15:31:30 -04:00
Lawrence Forman
7eedfc201a @0x/contracts-utils: Add testing against reference functions in SafeMath unit tests. 2019-08-06 15:31:30 -04:00
Lawrence Forman
ac38390241 @0x/contracts-utils: Fix failing test due to rebase. 2019-08-06 15:31:30 -04:00
Lawrence Forman
3156f602dd Fix rebase errors 2019-08-06 15:31:30 -04:00
Lawrence Forman
ad25942731 @0x/dev-utils: Appease the linter gods. 2019-08-06 15:31:30 -04:00
Lawrence Forman
fddbfc2d32 Update CHANGELOGs 2019-08-06 15:31:30 -04:00
Lawrence Forman
8c9bdadf66 @0x/contracts-utils: Add unit tests for ReferenceFunctions. 2019-08-06 15:30:59 -04:00
Lawrence Forman
6345faa4a9 `@0x/contracts-exchange-libs: Appease the linter and prettier gods. 2019-08-06 15:30:59 -04:00
Lawrence Forman
4711ce5532 @0x/contracts-exchange: Remove _assertValidFill().
`@0x/contracts-exchange`: Add `_settleOrder()` unit tests.
`@0x/contracts-exchange`: Add explicit tests for
`_calculateFillResults()`.
`@0x/contracts-exchange`: Add overflow tests to `isolated_fill_order`
tests.
`@0x/contracts-exchange`: Add explicit `takerAssetFillAmount = 0` test
to `isolated_fill_order` tests.
2019-08-06 15:30:59 -04:00
Lawrence Forman
293510c087 @0x/contracts-exchange-libs: Add explicit tests for LibMath and LibFillResults functions.
`@0x/contracts-exchange-libs`: Add tests for `ReferenceFunctions`.
2019-08-06 15:30:59 -04:00
Lawrence Forman
a179a6892c @0x/contracts-test-utils: Add ONE_ETHER and MAX_UINT256_ROOT constants. 2019-08-06 15:30:59 -04:00
Lawrence Forman
afb310e90a @0x/contracts-exchange: Update changelog. 2019-08-06 15:30:59 -04:00
Lawrence Forman
51391b7f0e @0x/contracts-exchange-libs: Correct internal variable naming in src/index.ts.
`@0x/contracts-utils`: Correct internal variable naming in `src/index.ts`.
`@0x/contracts-exchange`: Remove functions from `TestExchangeInternals.sol` that are now in other packages.
`@0x/contracts-exchange`: Remove `TestExchangeMath.sol`. Exchange math functions are now tested in `@0x/contracts-exchange-libs`.
`@0x/contracts-exchange`: Move `ReferenceFunctions` to default package export.
`@0x/contracts-exchange`: Update `match_order.ts` tests to use reference math functions instead of `TestExchangeMath`.
`@0x/contracts-exchange`: Remove `_updateFilledState()` combinatorial tests in favor of normal unit testing. Combinatorial testing was overkill.
`@0x/contracts-exchange`: Update/refactor `calculateFillResults()` combinatorial tests to use the reference functions and hide them behind `TEST_ALL`.
2019-08-06 15:30:59 -04:00
Lawrence Forman
264b1d69d9 @0x/dev-utils: revertWith mocha extensions now accept Promise-like objects instead of just Promises. 2019-08-06 15:30:59 -04:00
Lawrence Forman
884b1add8e @0x/contracts-exchange-libs: Move in revamped LibFillResults tests from @0x/contracts-exchange. 2019-08-06 15:30:59 -04:00
Lawrence Forman
8c05a92a1e Update changelogs 2019-08-06 15:30:59 -04:00
Lawrence Forman
f791cd3a37 @0x/contracts-exchange-libs: Remove unecessary checks for zero
denominator.
`@0x/contracts-exchange-libs`: `LibMath` tests from `@0x/contracts-exchange` into this package.
`@0x/contracts-exchange-libs`: Adjust logic in reference functions to be
closer to solidity implementation.
2019-08-06 15:30:30 -04:00
Lawrence Forman
4600a656d1 @0x/contracts-test-utils: Update testWithReferenceFunctionAsync() to
support `RevertError`s.
2019-08-06 15:30:30 -04:00
Lawrence Forman
d03f13a729 @0x/contracts-utils: LibMath._safeDiv() now throws a rich revert when dividing by zero. 2019-08-06 15:30:30 -04:00
Lawrence Forman
5a088690b2 @0x/utils: Add SafeMathRevertErrors.SafeMathErrorCodes.Uint256DivisionByZero. 2019-08-06 15:30:30 -04:00
Lawrence Forman
8d26f58dfa @0x/contracts-test-utils: Make testCombinatoriallyWithReferenceFuncAsync not async. 2019-08-06 15:30:30 -04:00
Lawrence Forman
a3cdb63ae1 @0x/contracts-exchange: Rename TestIsolatedExchange to just IsolatedExchange. 2019-08-06 15:30:30 -04:00
Lawrence Forman
9d5b23acd3 @0x/contracts-exchange: Update tests in isolated_fill_order.ts. 2019-08-06 15:30:30 -04:00
Lawrence Forman
41e04c0178 @0x/contracts-exchange: Add a buttload of tests to
`isolated_fill_order.ts`.
2019-08-06 15:30:30 -04:00
Lawrence Forman
abaa0cf3d0 @0x/contracts-test-utils: Move OrderInfo to @0x/types. 2019-08-06 15:30:30 -04:00
Lawrence Forman
8670fbe2ae @0x/types: Add OrderInfo type. 2019-08-06 15:30:30 -04:00
Lawrence Forman
898213bb85 @0x/contracts-exchange: Update tests for moved types. 2019-08-06 15:30:30 -04:00
Lawrence Forman
c30d59d5d3 @0x/types: Add FillResults, MatchedFillResults, and
`BatchMatchedFillResults` types.
`@0x/contracts-utils`: Add reference functions for `SafeMath`.
`@0x/contracts-exchange-libs`: Add reference functions for `LibMath` and
`LibFillResults`.
`@0x/contracts-test-utils`: Move `*FillResults` types to `@0x/types`.
`@0x/contracts-test-utils`: Add `log_utils.ts`.
`@0x/contracts-test-utils`: Add `hexRandom()` to `hex_utils.ts`.
`@0x/contracts-test-utils`: Add the contstants: `MAX_UINT256`,
`ADDRESS_LENGTH`.
2019-08-06 15:30:30 -04:00
Lawrence Forman
c54d69e5ae @0x/contracts-exchange: Create reference functions test util.
`@0x/contracts-exchange`: Use reference functions to assert fill results
in `isolated_fill_order` tests.
2019-08-06 15:27:39 -04:00
Lawrence Forman
38a1f08413 @0x/contracts-test-utils: Add MAX_UINT256 constant. 2019-08-06 15:27:39 -04:00
Lawrence Forman
e2bd80253b @0x/contracts-exchange: More TestIsolatedExchange rework. 2019-08-06 15:27:39 -04:00
Lawrence Forman
039cc6e28b @0x/contracts-exchange: Allow fetching of balance of multiple assets
in `TestIsolatedExchange` contract.
`@0x/contracts-exchange`: Refactor `IsolatedExchangeWrapper` to be more
extensible.
2019-08-06 15:27:39 -04:00
Lawrence Forman
1030c96eec @0x/contracts-exchange: Create IsolatedExchangeWrapper class. 2019-08-06 15:27:39 -04:00
Lawrence Forman
0851c5ac8e @0x/contracts-exchange: Run prettier. 2019-08-06 15:27:39 -04:00
Lawrence Forman
92d112083e @0x/contracts-test-utils: Add filterLogs() and
`filterLogsToArguments()` helpers.
2019-08-06 15:27:39 -04:00
Lawrence Forman
1e462f5cc0 @0x/contracts-test-utils: Add ADDRESS_LENGTH constant. 2019-08-06 15:27:39 -04:00
Lawrence Forman
d974ee169a @0x/contracts-exchange: Rename TestExchangeIsolated.sol ->
`TestIsolatedExchange.sol`.
`@0x/contracts-exchange`: Automatically track raw asset balances in
`TestIsolatedExchange` contract.
2019-08-06 15:27:39 -04:00
Lawrence Forman
7fb87d4039 @0x/contracts-exchange: Update signature and rich error decoder tests
to use `hexRandom()` and `blockchainTests()`.
2019-08-06 15:27:39 -04:00
Lawrence Forman
fc5963fa3d @0x/contracts-test-utils: Add hexRandom() to hex_utils.ts. 2019-08-06 15:27:39 -04:00
Lawrence Forman
cfa362321d @0x/contracts-exchange: Switch to TestExchangeIsolated contract for
`isolated_fill_order` tests.
2019-08-06 15:27:39 -04:00
Lawrence Forman
72c7157138 @0x/contracts-exchange: Start work on isolated fill order tests. 2019-08-06 15:27:39 -04:00
Amir Bandeali
2f91a12f19 Merge pull request #2019 from jalextowle/feature/contracts/3.0/disallow-address-zero
Disallow Zero address in MixinAuthorizable and Ownable
2019-08-06 10:13:28 -07:00
Amir Bandeali
abe72b7745 Merge pull request #1975 from 0xProject/feat/3.0/removeCancelOrderNoThrow
Use less strict validation in `cancelOrder`, remove `cancelOrderNoThrow`
2019-08-06 10:11:34 -07:00
Amir Bandeali
e7df9d1754 Update cancelOrder and batchCancelOrders tests 2019-08-05 10:35:25 -07:00
Amir Bandeali
d3ab2b077a Remove cancelOrderNoThrow tests 2019-08-05 10:33:21 -07:00
Amir Bandeali
467a11f4b4 Remove cancelOrderNoThrow and batchCancelOrdersNoThrow 2019-08-05 10:33:21 -07:00
Amir Bandeali
6cb8c1df42 Noop on cancel if order is already unfillable 2019-08-05 10:33:21 -07:00
Alex Towle
3915c7e8f2 Addressed final review comments 2019-08-04 23:45:02 -07:00
Alex Towle
5ba0e0dc54 Updated the structure of the archive directory 2019-08-03 16:33:28 -07:00
Alex Towle
9a35e2db77 Ran prettier 2019-08-02 13:46:34 -07:00
Alex Towle
e204a6d1d0 Updated Changelog 2019-08-02 13:46:34 -07:00
Alex Towle
47ab2a1b1d Reverted the asset-proxy back to an older version of Ownable that it was actually deployed with 2019-08-02 13:46:34 -07:00
Alex Towle
6fc38292f2 Add RichErrors for Authorizable 2019-08-02 13:45:41 -07:00
Alex Towle
89d8df3385 Moved MixinAuthorizable to Authorizable and fixed imports 2019-08-02 13:45:41 -07:00
Alex Towle
9c7df2b41e Reverted MixinAuthorizable to old version and moved the new version to utils 2019-08-02 13:45:41 -07:00
Alex Towle
46f6816511 Updated changelogs and ran prettier 2019-08-02 13:45:12 -07:00
Alex Towle
858ccfa934 Disallow the zero address in MixinAuthorizable 2019-08-02 13:45:12 -07:00
Alex Towle
b4a3218b13 Disallow address zero in Ownable 2019-08-02 13:44:18 -07:00
James Towle
92a4556956 Merge pull request #2020 from jalextowle/feature/contracts/3.0/rewrite-dispatch-transfer-from
Rewrite _dispatchTransferFrom with a Solidity implementation
2019-08-02 13:42:36 -07:00
James Towle
bd42c33daa Merge pull request #2014 from jalextowle/feature/contracts/3.0/utils-unit-tests
Added Unit Tests to Utils
2019-08-02 13:42:14 -07:00
Alex Towle
e1796a9f0f Changed toBN to toBigNumber 2019-08-01 15:39:00 -07:00
Alex Towle
8c5c81fe70 Change all instances of throw to revert in it tests 2019-08-01 15:13:16 -07:00
Alex Towle
bf8fae2025 Update changelog 2019-08-01 14:53:01 -07:00
Alex Towle
7f2b715ceb Rewrite _dispatchTransferFrom with a Solidity implementation 2019-08-01 14:53:00 -07:00
Lawrence Forman
974189045a Merge pull request #2007 from 0xProject/feature/3.0/mocha-blockchain-extensions
Mocha extensions for smart contract tests
2019-08-01 09:43:35 -04:00
Alex Towle
77feaec444 Fixed lingering review comments 2019-07-31 13:59:33 -07:00
Alex Towle
e5b6921de9 Updated Changelog 2019-07-30 15:56:31 -07:00
Alex Towle
3ca3a2820d Fixed review comments 2019-07-30 15:53:01 -07:00
Lawrence Forman
9f4933e33d @0x/contracts-test-utils: Make BlockchainContextDefinition interface
more concise.
2019-07-30 16:59:52 -04:00
Lawrence Forman
3cf48a831b @0x/contracts-test-utils: Export a custom describe() instead of
extending Mocha's ambient declarations.
`@0x/contracts-exchange`: Use `describe.optional` instead of
`blockchainTests.optional` in `test/fill_order.ts`.
2019-07-30 16:59:52 -04:00
Lawrence Forman
930b742663 @0x/contracts-test-utils: Fix blockchain environment not being created
with top-level `blockchainTests.resets()` directive.
2019-07-30 16:59:52 -04:00
Lawrence Forman
d3870fed1c @0x/contracts-exchange: Update test/fill_order.ts to use the new
mocha blockchain extensions.
2019-07-30 16:59:52 -04:00
Lawrence Forman
99e242affd @0x/contracts-test-utils: Make blockchainTests() automatically call blockchainLifecycle.startAsync() and blockchainLifecycle.revertAsync() in a before() and after() directive. 2019-07-30 16:59:52 -04:00
Lawrence Forman
9792246970 @0x/contracts-test-utils: Tweak mocha blockchain extensions tests. 2019-07-30 16:59:52 -04:00
Lawrence Forman
020b953166 @0x/contracts-test-utils: Update CHANGELOG. 2019-07-30 16:59:52 -04:00
Lawrence Forman
52aa8e914a @0x/contracts-test-utils: Tweak mocha blockchain extensions tests. 2019-07-30 16:59:52 -04:00
Lawrence Forman
e01eadaecd @0x/contracts-exchange: Add tests and run prettier. 2019-07-30 16:59:52 -04:00
Lawrence Forman
61fc32b7c0 @0x/contracts-test-utils: Add optional modifier to blockchainTests(). 2019-07-30 16:59:52 -04:00
Lawrence Forman
a9c8207bb0 @0x/contracts-test-utils: Pass a more robust BlockchainTestsEnvironment object to blockchainTests() callback. 2019-07-30 16:59:52 -04:00
Lawrence Forman
eac4f172fe @0x/contracts-test-utils: Just do a naked mocha import in mocha_blockchain. 2019-07-30 16:59:52 -04:00
Lawrence Forman
d6271426fd @0x/contracts-test-utils: Rename blockchainTests.reset to blockchainTests.resets. 2019-07-30 16:59:52 -04:00
Lawrence Forman
7e59110049 @0x/contracts-test-utils: Create blockchainTests mocha fixture directive.
`@0x/contracts-test-utils`: Automatically call `chaiSetup.configure()`.
`@0x/contracts-test-utils`: Export `expect` as an alias for `chai.expect`.
2019-07-30 16:59:52 -04:00
James Towle
8cf4fb9adc Update contracts/utils/test/safe_math.ts
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-30 12:08:35 -07:00
James Towle
f044f364cb Update contracts/utils/test/reentrancy_guard.ts
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-30 12:08:35 -07:00
James Towle
4d39892a11 Update contracts/utils/test/ownable.ts
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-30 12:08:35 -07:00
James Towle
bf1ebe8e53 Update contracts/utils/test/ownable.ts
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-30 12:08:35 -07:00
James Towle
77b4f32274 Update contracts/utils/test/ownable.ts
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-30 12:06:35 -07:00
Alex Towle
b2ada13a21 Ran prettier 2019-07-30 12:06:35 -07:00
Alex Towle
03fced81f5 Added unit tests for LibRichErrors 2019-07-30 12:06:35 -07:00
Alex Towle
f9292a8fb8 Added unit tests for LibEIP712 2019-07-30 12:06:35 -07:00
Alex Towle
065f46a020 Added unit tests for LibAddress 2019-07-30 12:06:35 -07:00
Alex Towle
6efb7027b5 Added unit tests for ReentrancyGuard 2019-07-30 12:06:35 -07:00
Alex Towle
f4f922acb5 Added unit tests for Ownable 2019-07-30 12:06:35 -07:00
Alex Towle
4a4d2e7079 Added unit tests for SafeMath 2019-07-30 12:06:35 -07:00
Amir Bandeali
1634c90179 Merge pull request #2016 from 0xProject/fix/3.0/circleci-workflow-fix-90d1decb8
Fix circleci workflow failing on 3.0 branch
2019-07-30 12:06:28 -05:00
Lawrence Forman
9b5ba6806f @0x/contracts-asset-proxy: Fix broken erc1155_proxy tests.
`@0x/contracts-asset-proxy`: Add `ERC1155Proxy.sol` to .solhintignore.
Fix circleci config to work with 3.0 branch.
2019-07-29 23:47:04 -04:00
Lawrence Forman
4afca6ca8d Fix circleci workflow failing due to test-python being required in config. 2019-07-29 21:54:43 -04:00
Amir Bandeali
90d1decb87 Fix build errors 2019-07-24 10:26:28 -07:00
Alex Towle
1d8cb1b107 Addressed lingering review comments 2019-07-23 15:53:26 -07:00
Alex Towle
65e3d9873d Added ERC1155 Aggregation 2019-07-23 15:53:26 -07:00
Alex Towle
50b22c673e Addressed review comments 2019-07-23 15:53:26 -07:00
Alex Towle
4ef8b7f733 Rebased onto 3.0 2019-07-23 15:53:26 -07:00
James Towle
e0ec26255b Fixed lingering issues 2019-07-23 15:53:26 -07:00
James Towle
ffa32f7610 Changed the returndata for batchMatchOrders 2019-07-23 15:53:26 -07:00
James Towle
1c1d257bd9 Addressed lingering review comments 2019-07-23 15:53:26 -07:00
James Towle
5611cb91a0 Adapted tests from matchOrders to test matchOrdersWithMaximalFill 2019-07-23 15:53:26 -07:00
James Towle
e0cff4b74e Updated batchMatchOrders to fix an edge case and added tests 2019-07-23 15:53:26 -07:00
James Towle
c1985e6986 Addessed some review comments 2019-07-23 15:53:26 -07:00
James Towle
416b1aee98 Improved the testing for matchOrders and batchMatchOrders 2019-07-23 15:53:26 -07:00
James Towle
7bb9d8b03a Created a test for case 3 of matchOrdersWithMaximalFill 2019-07-23 15:53:26 -07:00
James Towle
0473c82029 Improved test coverage for batchMatchOrdersWithMaximalFill 2019-07-23 15:53:26 -07:00
James Towle
63bd1a4a22 Ran prettier 2019-07-23 15:53:26 -07:00
James Towle
5a64759c83 Added a reentrancy test for matchOrdersWithMaximalFill 2019-07-23 15:53:26 -07:00
James Towle
0df68a6e06 Added testing for the BatchMatchOrdersError Rich Error 2019-07-23 15:53:26 -07:00
James Towle
29eff3b515 Rebased onto PR #1900 2019-07-23 15:53:26 -07:00
James Towle
073976de10 Split up TestExchangeInternals into two contracts 2019-07-23 15:53:26 -07:00
James Towle
1fe159f432 Polished MixinMatchOrders and removed unimplemented test 2019-07-23 15:53:26 -07:00
James Towle
adad7f4e3f Modified the matchOrders tests to test matchOrdersWithMaximalFill 2019-07-23 15:53:26 -07:00
James Towle
378710533e Implemented matchOrdersWithMaximalFill 2019-07-23 15:53:26 -07:00
James Towle
d966848ef8 Implemented batchMatchOrdersWithMaximalFill 2019-07-23 15:53:26 -07:00
James Towle
d6d613ca37 Added a new test 2019-07-23 15:53:26 -07:00
James Towle
1a385de367 Improved the efficiency of batchMatchOrders 2019-07-23 15:53:25 -07:00
James Towle
73eb56c072 Added RichErrors to batchMatchOrders 2019-07-23 15:53:25 -07:00
James Towle
9651941cce Added getMatchOrdersResultsAsync and getBatchMatchOrdersResultsAsync 2019-07-23 15:53:25 -07:00
James Towle
29be79814f Added a test for partial matching 2019-07-23 15:53:25 -07:00
James Towle
1ea220f44f Removed batchMatchOrdersWithMaximumFill 2019-07-23 15:53:25 -07:00
James Towle
6cf11554de Created tests for batchMatchOrders 2019-07-23 15:53:25 -07:00
James Towle
f289b3112b Implemented batchMatchOrders 2019-07-23 15:53:25 -07:00
James Towle
c61df50167 Updated Changelogs 2019-07-23 15:53:25 -07:00
James Towle
df5ec33330 @0x:contracts-utils Address remaining review comments 2019-07-23 15:53:25 -07:00
James Towle
6384518ee1 @0x:contracts-exchange Updated LibMath to use library rich errors 2019-07-23 15:53:25 -07:00
James Towle
87bf940f89 @0x:contracts-exchange Refactor OrderTransferSimulationUtils 2019-07-23 15:53:25 -07:00
James Towle
53db047a4e @0x:contracts-exchange Eliminated code duplication within LibExchangeRichErrors and IExchangeRichErrors 2019-07-23 15:53:25 -07:00
James Towle
dabef47ce7 @0x:contracts-exchange Updated MixinTransactions to use library RichErrors 2019-07-23 15:53:25 -07:00
James Towle
4de1d69282 @0x:contracts-exchange Updated MixinMatchOrders to use library RichErrors 2019-07-23 15:53:25 -07:00
James Towle
015c35f2b2 @0x:contracts-exchange Updated MixinSignatureValidator to use library RichErrors 2019-07-23 15:53:25 -07:00
James Towle
5a491b2624 @0x:contracts-exchange Updated MixinWrapperFunctions to use library RichErrors 2019-07-23 15:53:25 -07:00
James Towle
3d95817dbe @0x:contracts-exchange Updated MixinAssetProxyDispatcher and MixinExchangeCore to use library RichErrors 2019-07-23 15:53:25 -07:00
James Towle
96ab74dea4 @0x:contracts-utils Refactored utils to exclusively use library RichErrors 2019-07-23 15:53:25 -07:00
James Towle
f937a0b038 @0x:contracts-utils Added RichErrors to ReentrancyGuard 2019-07-23 15:53:25 -07:00
James Towle
da38285046 @0x:contracts-utils Added RichErrors to LibAddressArray 2019-07-23 15:53:25 -07:00
James Towle
d3db2dcfbb @0x:contracts-utils Added RichErrors to LibBytes 2019-07-23 15:53:25 -07:00
Lawrence Forman
c788db785b @0x/contracts-exchange: Use named return values in MixinSignatureValidator.sol 2019-07-23 15:53:25 -07:00
Lawrence Forman
6df41d2562 @0x/contracts-exchange: REALLY make assertValidFill() internal again. 2019-07-23 15:53:25 -07:00
Lawrence Forman
74fb43998e @0x/contracts-exchange: Make assertValidFill() internal again. 2019-07-23 15:53:25 -07:00
Lawrence Forman
c1f8eabd12 @0x/contracts-exchange: Cosmetic changes to contracts. 2019-07-23 15:53:25 -07:00
Lawrence Forman
2f5a1eebe0 @0x/contracts-exchange: Make assertValidFill and calculateMatchedFillResults public 2019-07-23 15:53:25 -07:00
Lawrence Forman
4791c120fe @0x/contracts-exchange: Run contracts:gen 2019-07-23 15:53:24 -07:00
Lawrence Forman
f6d445b553 @0x/order-utils: Update CHANGELOG 2019-07-23 15:53:24 -07:00
Lawrence Forman
db3dd4ae5a @0x/contracts-exchange: Update CHANGELOG 2019-07-23 15:53:24 -07:00
Lawrence Forman
d6ba03916a @0x/contracts-exchange: Update tests for new/consolidated signature types.
`@0x/contracts-exchange`: Update `Whitelist` example for new signature types.
2019-07-23 15:53:24 -07:00
Lawrence Forman
4734acbe61 @0x/contracts-test-utils: Add hexConcat() in hex_utils.ts. 2019-07-23 15:53:24 -07:00
Lawrence Forman
527256b416 @0x/contracts-exchange: Remove isValidOrderSignature() from IWallet. 2019-07-23 15:53:24 -07:00
Lawrence Forman
7a0dc7a364 @0x/contracts-exchange: Add isValidHashSignature() back.
`@0x/contracts-exchange`: Remove references to removed signature types and associated functions.
2019-07-23 15:53:24 -07:00
Lawrence Forman
7f88e8ad6e @0x/order-utils: Remove unused exchange revert errors 2019-07-23 15:53:24 -07:00
Lawrence Forman
c7324121ed @0x/types: Consolidate signature types. 2019-07-23 15:53:24 -07:00
Lawrence Forman
588ca3a315 @0x/contracts-exchange: Fix linearization issues. 2019-07-23 15:53:24 -07:00
Lawrence Forman
eb9b2f355e @0x/contracts-exchange: Consolidate signature types.
`@0x/contracts-exchange`: Fighting with linearization issues.
2019-07-23 15:53:24 -07:00
Lawrence Forman
cf6144599d Fix linter errors 2019-07-23 15:53:24 -07:00
Lawrence Forman
c23bb5e589 @0x/contracts-exchange: Add comments about preserving signatures in MixinSignatureValidator.sol 2019-07-23 15:53:24 -07:00
Lawrence Forman
0eb5c825a5 @0x/contracts-exchange: Refactor out EIP1271_MAGIC_VALUE into a LibEIP1271 contract and inherit from that.
`@0x/contracts-exchange`: Use `LibBytes.readBytes4()` to validate EIP1271 return values and be more permissive of shorter return values.
`@0x/contracts-exchange`: Use `abi.decode()` for `EIP1271OrderWallet` in `TestSignatureValidator.sol`.
`@0x/contracts-exchange`: Correct minor formatting changes in contracts.
2019-07-23 15:53:24 -07:00
Lawrence Forman
5dfb65b084 @0x/contracts-exchange: Fix comments in test/signature_validator.ts 2019-07-23 15:53:24 -07:00
Lawrence Forman
ddbe2acbf5 @0x/contracts-utils: Add LibEIP1271.sol 2019-07-23 15:53:24 -07:00
Lawrence Forman
2ff3735adc Rebase against 3.0 2019-07-23 15:53:24 -07:00
Lawrence Forman
c2752d5931 Update changelogs 2019-07-23 15:53:24 -07:00
Lawrence Forman
309dd7f300 Run prettier/linter 2019-07-23 15:53:24 -07:00
Lawrence Forman
33df11b755 @0x/contracts-exchange: Rename WalletOrderValidator to OrderWallet signature type
`@0x/contracts-exchange`: Rename `SignatureWalletOrderValidatorError` to `SignatureOrderWalletError`
`@0x/contracts-exchange`: Add `IEIP1271Wallet` interface
`@0x/contracts-exchange`: Add `EIP1271Wallet` and `EIP1271OrderWallet` to `SignatureType`
`@0x/contracts-exchange`: Always check `OrderValidator`, `OrderWallet`, `EIP1271OrderWallet` signature types on every fill
`@0x/contracts-exchange`: Add tests for EIP1271 signature types.
`@0x/contracts-exchange`: Update `LibExchangeRichErrorDecoder` for new/renamed Error types.
2019-07-23 15:53:24 -07:00
Lawrence Forman
bd5babf65d @0x/order-utils: Rename SignatureWalletOrderValidatorError to SignatureOrderWalletError RevertError type. 2019-07-23 15:53:24 -07:00
Lawrence Forman
3c07cbde47 @0x/types: Rename WalletOrderValidator to OrderWallet in SignatureType
`@0x/types`: Add `EIP1271Wallet` and `EIP1271OrderWallet` to `SignatureType`
2019-07-23 15:53:24 -07:00
Lawrence Forman
dee5ff852d @0x/contracts-exchange: Have TestValidatorWallet always accept WalletOrderValidator if makerAddress == this.
`@0x/contracts-exchange`: Update tests for repeatable signature validation.
2019-07-23 15:53:24 -07:00
Lawrence Forman
073930004d @0x/order-utils: Add validator field to SignatureOrderValidatorError and SignatureValidatorError RevertError types.
`@0x/order-utils`: Add `SignatureOrderValidatorNotApprovedError` and `SignatureValidatorNotApprovedError` `RevertError` types.
2019-07-23 15:53:24 -07:00
Lawrence Forman
01574c5a87 @0x/contracts-exchange: Update changelog 2019-07-23 15:53:24 -07:00
Lawrence Forman
3a49369e68 @0x/utils: Add toStringTag symbol to RevertError 2019-07-23 15:53:24 -07:00
Lawrence Forman
42f7b7cc19 @0x/contracts-exchange: Always check OrderValidator and WalletOrderValidator signature types on every fill
`@0x/contracts-exchange`: Add `validatorAddress` field to `SignatureValidatorError` and `SignatureOrderValidatorError` rich reverts
`@0x/contracts-exchange`: Add separate `SignatureOrderValidatorNotApprovedError` for `OrderValidator` signatures
`@0x/contracts-exchange`: Consolidate Wallet and Validator test contracts into a single configurable `TestValidatorWallet` contract.
`@0x/contracts-exchange`: Rewrite many tests in `signature_validator.ts` for brevity.
2019-07-23 15:53:24 -07:00
Lawrence Forman
5f8ebc3601 @0x/base-contract: Make PromiseWithTransactionHash fully compatible with regular Promise types.
`@0x/contracts/exchange` Make `OrderValidator` and `WalletOrderValidator` signature types checked for every fill (not just first)'
2019-07-23 15:53:24 -07:00
Lawrence Forman
2e5645108b Update generated wrappers for coordinator and exchange. 2019-07-23 15:53:24 -07:00
Amir Bandeali
d73f7beb2f Fix StaticCallProxy Exchange integration tests 2019-07-23 15:52:20 -07:00
Amir Bandeali
4f6f126952 Fix build 2019-07-23 15:52:20 -07:00
Amir Bandeali
0099cdd6ad Update comments and add a catch-all else in getSimulatedOrderTransferResults function 2019-07-23 15:52:20 -07:00
Amir Bandeali
2b7114b704 Update CHANGELOGs 2019-07-23 15:52:20 -07:00
Amir Bandeali
2041d0d000 Add fillOrder transfer ordering tests 2019-07-23 15:52:20 -07:00
Amir Bandeali
698f313b73 Reorder matchOrder transfers and remove redundant checks 2019-07-23 15:52:20 -07:00
Amir Bandeali
1940458306 Add tests for OrderTransferSimulationUtils 2019-07-23 15:52:20 -07:00
Amir Bandeali
983def2bbd Add OrderTransferSimulationUtils 2019-07-23 15:52:20 -07:00
Amir Bandeali
9213bf47ae Swap ordering of transfers in fills and remove redundant checks 2019-07-23 15:52:20 -07:00
Amir Bandeali
f01743e27c Add tests for simulateTransferFromCalls 2019-07-23 15:52:20 -07:00
Amir Bandeali
9be58972a0 Add MixinTransferSimulator 2019-07-23 15:52:20 -07:00
James Towle
a1a6c3e40c Updated the DivisionByZeroError to not use assembly 2019-07-23 15:52:20 -07:00
James Towle
a2b19a1b9d Updated DivisionByZero error 2019-07-23 15:52:20 -07:00
James Towle
4d1a942e79 Removed unnecessary files and code 2019-07-23 15:52:20 -07:00
James Towle
eb4afa8f2c Update contracts/exchange-libs/contracts/src/interfaces/IMixinLibMathRichErrors.sol
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-23 15:52:20 -07:00
James Towle
468bbea44d Update contracts/exchange-libs/contracts/src/interfaces/IMixinLibMathRichErrors.sol
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-23 15:52:20 -07:00
James Towle
b75aa02b0d Update contracts/exchange/test/internal.ts
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-23 15:52:20 -07:00
James Towle
a39f93bcff Update contracts/exchange/test/internal.ts
Co-Authored-By: Lawrence Forman <lawrence@0xproject.com>
2019-07-23 15:52:20 -07:00
James Towle
e229d2d59f Updated tests to work with LibMathRichErrors 2019-07-23 15:52:20 -07:00
James Towle
3d58dc2a50 Added RichReverts to exchange-libs 2019-07-23 15:51:43 -07:00
James Towle
0395188aed Updated any remaining contracts using 0.5.5 to 0.5.9 2019-07-23 15:51:43 -07:00
James Towle
4e6dd1b213 Updated the style 2019-07-23 15:51:43 -07:00
James Towle
a46b13967a Refactored the SafeMath errors 2019-07-23 15:51:43 -07:00
James Towle
e916daf5fd Ran yarn prettier 2019-07-23 15:51:43 -07:00
James Towle
fad9dae9bb Fixed the exchange unit tests 2019-07-23 15:51:43 -07:00
James Towle
83bd5f5561 Fixed the last broken test in asset-proxy 2019-07-23 15:51:43 -07:00
James Towle
0ddb9f8923 Added a linting command for slower computers 2019-07-23 15:51:43 -07:00
James Towle
03ea97734c Ran yarn prettier 2019-07-23 15:51:43 -07:00
James Towle
b7adf59ed5 Fixed any lingering style issues 2019-07-23 15:51:43 -07:00
James Towle
666b992c51 Readded Underflow RichErrors to asset-proxy 2019-07-23 15:51:43 -07:00
James Towle
56d5e9c889 Fixed the build issues in exchange 2019-07-23 15:51:43 -07:00
James Towle
aa36ebf4f2 Removed RichErrors from the erc1155 test in Authorizable 2019-07-23 15:51:43 -07:00
James Towle
de60123ec7 Updated the combanatorial tests to use RichErrors 2019-07-23 15:51:43 -07:00
James Towle
cf3790c2f8 Updated the erc1155 tests in asset-proxy to use RichErrors 2019-07-23 15:51:43 -07:00
James Towle
b7bac3abf6 Updated the asset-proxy tests to use RichErrors 2019-07-23 15:51:43 -07:00
James Towle
f4551dd1e5 Updated the exchange tests to use RichErrors 2019-07-23 15:51:43 -07:00
James Towle
b3da4bb5b7 Updated the erc1155 tests to expect RichErrors 2019-07-23 15:51:43 -07:00
James Towle
6e4b6929d2 Added RichErrors to SafeMath 2019-07-23 15:51:43 -07:00
James Towle
a0602c8863 Added RichErrors to Ownable 2019-07-23 15:51:43 -07:00
James Towle
55246c5d87 Removed unnecessary import 2019-07-23 15:51:43 -07:00
James Towle
81ee577407 Updated naming in MixinTransactions 2019-07-23 15:51:43 -07:00
James Towle
55e1045000 Added a comment about inheritance in the exchange 2019-07-23 15:51:43 -07:00
James Towle
fc96df63fd Fixed most of the nits 2019-07-23 15:51:43 -07:00
James Towle
9b787a6bc2 Removed enums from Mixins in the coordinator package 2019-07-23 15:51:43 -07:00
James Towle
201dc7c28d Removed events from the Mixins in asset-proxy 2019-07-23 15:51:43 -07:00
James Towle
5189fa6483 Fixed the inheritance hierarchy 2019-07-23 15:51:43 -07:00
James Towle
1992478cee Updated the mixins 2019-07-23 15:51:43 -07:00
James Towle
5ad6b48289 Refactored into interfaces 2019-07-23 15:51:43 -07:00
James Towle
bbcf83b99d Added a linting command that only runs on contracts 2019-07-23 15:51:43 -07:00
James Towle
9ef55023f2 Removed all mixins/ directories from the repository 2019-07-23 15:51:43 -07:00
Amir Bandeali
f2f81b0f7b Fix dev-utils tests 2019-07-23 15:51:43 -07:00
Amir Bandeali
c22ed861d1 Remove ZRX fees from dev-utils contracts 2019-07-23 15:51:43 -07:00
Amir Bandeali
39bed4d306 temp 2019-07-23 15:51:43 -07:00
Amir Bandeali
949946589f Fix order-utils tests 2019-07-23 15:50:36 -07:00
Amir Bandeali
09d970f056 Update abi-gen-wrappers 2019-07-23 15:50:36 -07:00
James Towle
5813bb9ca8 Updated any remaining contracts using 0.5.5 to 0.5.9 2019-07-23 15:46:16 -07:00
Amir Bandeali
c48ad5c90f Fix outdated comments 2019-07-23 15:46:16 -07:00
Amir Bandeali
4fdc1b3e19 Update CHANGELOGs 2019-07-23 15:46:16 -07:00
Amir Bandeali
dc372a43fe Fix incorrect function call for fillOrderNoThrow test 2019-07-23 15:46:16 -07:00
Amir Bandeali
589b791cd7 Add names to return values and fix breaking transactions tests 2019-07-23 15:46:16 -07:00
Amir Bandeali
564dbea126 Remove formatters and clarify comments about pointing assetData to the same memory location 2019-07-23 15:46:16 -07:00
Amir Bandeali
1bc4bc613e Add return value checks to wrapper tests 2019-07-23 15:46:16 -07:00
Amir Bandeali
11a25cb1ae Return FillResults[] for batch fill methods 2019-07-23 15:46:16 -07:00
Lawrence Forman
d6c1bf691c Reorder event assertions in transactions tests. 2019-07-23 15:46:16 -07:00
Amir Bandeali
e6443a2612 Update CHANGELOGs 2019-07-23 15:46:16 -07:00
Amir Bandeali
d79714a3cf Fix merge conflict remnant 2019-07-23 15:46:15 -07:00
Amir Bandeali
4bb1312cf1 Fix coordinator package build 2019-07-23 15:46:15 -07:00
Amir Bandeali
4e2abcaefa Fix linting errors 2019-07-23 15:46:15 -07:00
Amir Bandeali
d463d4c46b Add transaction expiration tests 2019-07-23 15:46:15 -07:00
Amir Bandeali
435c81da98 Revert if transaction is expired 2019-07-23 15:46:15 -07:00
Amir Bandeali
4f818d55fa Add TransactionExecution log tests 2019-07-23 15:46:15 -07:00
Amir Bandeali
c96a81e319 Fix exchange package build 2019-07-23 15:46:15 -07:00
Amir Bandeali
7cff9ba86a Refactor tests 2019-07-23 15:46:15 -07:00
Amir Bandeali
6ddaa6f52a Add expirationTimeSeconds to ZeroExTransaction schema throughout codebase 2019-07-23 15:46:15 -07:00
Amir Bandeali
238877b627 Log TransactionExecution event when transaction is successfully executed 2019-07-23 15:46:15 -07:00
Lawrence Forman
95e7999e45 @0x/contracts-exchange: Update settlement test simulators to match settlement optimizations in the Exchange. 2019-07-23 15:46:15 -07:00
Lawrence Forman
2f464ee8f0 @0x/contracts-exchange: Fix critical error in fillOrder() and matchOrders() redundant transfer optimization code.
`@0x/contracts-exchange`: Rearrange `Fill` event params to make regular `emit` code work without breaking the stack.
`@0x/contracts-exchange`: Add edge case tests for redundant transfer optimizations.
2019-07-23 15:46:15 -07:00
Lawrence Forman
8fe9883b62 Update contracts/exchange/contracts/src/MixinMatchOrders.sol
`@0x/contracts-exchange`: Minor code change to save an mload.
2019-07-23 15:46:15 -07:00
Lawrence Forman
de896f9159 @0x/contracts-exchange: Remove TODO comment in fill_order_combinatorial_utils.ts. 2019-07-23 15:46:15 -07:00
Lawrence Forman
a2468e8129 @0x/contracts-exchange: Update changelog. 2019-07-23 15:46:15 -07:00
Lawrence Forman
ee89f74afd @0x/contracts-exchange: Avoid redundant transfer in matchOrders() when maker/feeRecipient and takerAssetData/makerFeeAssetData are the same.
`@0x/conracts-exchange`: Disable combinatorial tests by default. Can be run by setting env var `TEST_ALL=1`.
2019-07-23 15:46:15 -07:00
Lawrence Forman
cd08c3e8fa @0x/contracts-exchange: Avoid redundant trasfer in fillOrder() when maker/taker is the same as feeRecipient and the assets match.
`@0x/contracts-exchange`: Swap fill order in `fillOrder()` from maker -> taker to taker -> maker first
2019-07-23 15:46:15 -07:00
Lawrence Forman
9cc8933eec @0x/contracs-test-utils: Increase number of deployed ERC721 and ERC1155 tokens to 2 to fix broken asset-proxy tests. 2019-07-23 15:46:15 -07:00
Lawrence Forman
91c27ff972 @0x/contracts-exchange: Fix build error. 2019-07-23 15:46:15 -07:00
Lawrence Forman
07e3ba014c @0x/contracts-exchange: Fully incorporate ERC1155 and MultiAsset tests into the fillOrder and matchOrders test suites. 2019-07-23 15:46:15 -07:00
Lawrence Forman
57ac0ca6e8 @0x/contracts-test-utils: Reduce number of test token deployments to speed up tests. 2019-07-23 15:46:15 -07:00
Lawrence Forman
816368b1fe @0x/contracts-exchange: Re-eanble all exchange tests.
`@0x/contracts-echange`: Set up 1155 and MAP proxies for `matchOrders()` tests.
2019-07-23 15:46:15 -07:00
Lawrence Forman
85ea291745 @0x/contracts-exchange: Add MultiAssetProxy, ERC1155Fungible, and ERC1155NonFungible combinatorial tests. 2019-07-23 15:46:15 -07:00
Lawrence Forman
741fdfa52e @0x/contracts-erc1155: Add mintKnownFungibleTokensAsync(), isNonFungibleItemAsync(), isFungibleItemAsync(), getOwnerOfAsync(), getBalanceAsync() to Erc1155Wrapper. 2019-07-23 15:46:15 -07:00
Lawrence Forman
348ec5bc3c @0x/contracts-asset-proxy: Add setProxyAllowanceForAllAsync() to ERC1155ProxyWrapper. 2019-07-23 15:45:39 -07:00
Lawrence Forman
df9698ab1f @0x/order-utils: Add ERC1155 to ExchangeTransferSimulator and fix MultiAssetProxy transfer accounting. 2019-07-23 15:45:39 -07:00
Lawrence Forman
c1aead970a Disable staking package from CI. 2019-07-23 15:45:39 -07:00
Lawrence Forman
518f351235 @0x/contracts-exchange: Correct coding convention in match_orders.ts 2019-07-23 15:44:58 -07:00
Lawrence Forman
d79a07e2c4 @0x/contracts-exchange: Fix indentation in matchOrders(). 2019-07-23 15:44:58 -07:00
Lawrence Forman
b636057251 @0x/contracts-exchange-libs: Make EIP712_ORDER_SCHEMA_HASH public. 2019-07-23 15:44:58 -07:00
Lawrence Forman
c692c8f055 @0x/contracts-exchange-libs: Regenerate LibExchangeSelectors.sol 2019-07-23 15:44:58 -07:00
Lawrence Forman
930736060c @0x/abi-gen-templates: Automatically catch and decode ganache revert Errors in transaction methods. 2019-07-23 15:44:58 -07:00
Lawrence Forman
1c8468d248 @0x/contracts-exchange: Use function/event selectors from LibExchangeSelectors.
`@0x/contracts-exchange`: Add memory map comments to `Fill` emit code.
2019-07-23 15:43:23 -07:00
Lawrence Forman
575842eab4 @0x/contracts-exchange-libs: Convert generate-exchange-selectors script to typescript. 2019-07-23 15:43:23 -07:00
Lawrence Forman
f7f55cad43 @0x/contracts-exchange: Removed dependency on OrderValidationUtils. The tests using it didn't really warrant the full validation suite.
`@0x/contracts-test-utils`: Move all the `OrderScenario` related types into the `contracts-exchange` package because no one else is using them.
2019-07-23 15:43:23 -07:00
Lawrence Forman
acd857a8c0 @0x/contracts-asset-proxy: Fix broken proxies test. 2019-07-23 15:43:23 -07:00
Lawrence Forman
53ff248176 @0x/contracts-exchange: Revert internal tests. 2019-07-23 15:43:23 -07:00
Lawrence Forman
3de13967bc @0x/base-contract: Re-wrap StringRevertErrors as plain Errors for backwards compatibility 2019-07-23 15:43:23 -07:00
Lawrence Forman
aebb923c2d @0x/contracts-exchange: Major rework of fill_order_combinatorial_utils.
`@0x/contracts-exchange`: Add more arbitrary fee token tests.
`@0x/contracts-exchange`: Fix broken tests.
2019-07-23 15:43:23 -07:00
Lawrence Forman
76d577a08d @0x/contracts-test-utils: Add more OrderScenario related types. 2019-07-23 15:43:23 -07:00
Lawrence Forman
3fb34a2a83 @0x/contracts-asset-proxy: Make setProxyAllowanceForAll() just accept a ownerAddress and give the proxy full control. 2019-07-23 15:43:23 -07:00
Lawrence Forman
cdb938ea28 @0x/base-contract: Add a method for converting Error types to RevertErrors.
`@0x/abi-gen-templates`: Automatically try to convert `Error`s thrown in `callAsync()` to `RevertError`s.
`@0x/abi-gen-wrappers`: Update generated wrappers.
2019-07-23 15:43:23 -07:00
Lawrence Forman
882dd4597e @0x/dev-utils: Move Error -> RevertError coercion logic to @0x/utils. 2019-07-23 15:27:39 -07:00
Lawrence Forman
409efb8c67 @0x/order-utils: Update RevertError types for new RevertError constructor. 2019-07-23 15:27:39 -07:00
Lawrence Forman
eaa4373a18 @0x/utils: Tweak RevertError to produce a meaningful Error message/stack trace.
`@0x/utils`: Add more `RevertError` decoding/transforming functions (such as `decodeThrownErrorAsRevertError()`)
2019-07-23 15:27:39 -07:00
Lawrence Forman
d480f8d82a @0x/web3-wrapper: Let toBaseUnitAmount() accept a number as well as a BigNumber 2019-07-23 15:27:39 -07:00
Lawrence Forman
339fc9ff14 @0x/assert: Add isNumberLike assertion 2019-07-23 15:27:00 -07:00
Lawrence Forman
14167412e0 @0x/contracts-exchange-libs: Make generate-exchange-selectors terminate file with a newline. 2019-07-23 15:26:59 -07:00
Lawrence Forman
7c0f075d1f Update changelogs with PR #s 2019-07-23 15:26:59 -07:00
Lawrence Forman
f4aea76c6e Ran prettier 2019-07-23 15:26:59 -07:00
Lawrence Forman
d263382365 @0x/contracts-coordinator: Fix broken coordinator tests. 2019-07-23 15:26:59 -07:00
Lawrence Forman
2109ed8464 @0x/contracts-exchange-libs: Add generate-exchange-selectors package script to regenerate LibExchangeSelectors from Exchange artifacts. 2019-07-23 15:26:59 -07:00
Lawrence Forman
d11444b983 @0x/contracts-exchange: Fix Exchange Wrappers tests. 2019-07-23 15:26:59 -07:00
Lawrence Forman
0508a45681 @0x/contracts-echange: Fix transactions test bug with ExchangeWrapper example due to deduping. 2019-07-23 15:26:59 -07:00
Lawrence Forman
a5c0b95f8b Update changelogs 2019-07-23 15:26:59 -07:00
Lawrence Forman
f1af12b3b9 Update CI config to blacklist contracts-extensions and contracts-exchange-forwarder. 2019-07-23 15:26:59 -07:00
Lawrence Forman
9d257497bd Ran prettier and fixed linter errors 2019-07-23 15:23:40 -07:00
Lawrence Forman
79f40b4ce0 @0x/contracts-exchange: Enable all exchange tests. 2019-07-23 15:23:40 -07:00
Lawrence Forman
1ab62b7a80 @0x/contracts-exchange: Fix broken match orders tests 2019-07-23 15:23:40 -07:00
Lawrence Forman
d2f10d5834 @0x/contracts-exchange: Allow custom ExchangeWrapper.matchOrders() call in MatchOrdersTester. 2019-07-23 15:23:40 -07:00
Lawrence Forman
c326ec9d1e @0x/contracts-exchange: Rewrote MatchOrderTester class to be simpler and more flexible. 2019-07-23 15:23:40 -07:00
Lawrence Forman
26317d16ff @0x/contracts-exchange: Fix matchOrders() not paying fees if same feeRecipient but different feeAssetDatas. 2019-07-23 15:23:40 -07:00
Lawrence Forman
79b8f85cdf @0x/contracts-test-utils: Remove TransferAmountsByMatchOrders and TransferAmountsLoggedByMatchOrders.
`@0x/contracts-test-utils`: Add `TokenBalancesByOwner` type.
2019-07-23 15:23:40 -07:00
Lawrence Forman
c84a0b8415 @0x/contracts-exchange: Fix matchOrders and signature tests. 2019-07-23 15:23:40 -07:00
Lawrence Forman
be5336d074 @0x/contracts-exchange: Enable all tests. 2019-07-23 15:23:40 -07:00
Lawrence Forman
aecb2efad9 @0x/contracts-exchange: Fix combinatorial fillOrder test bugs.
`@0x/contracts-exchange`: Fix emit `Fill` event code.
2019-07-23 15:23:40 -07:00
Lawrence Forman
3654005c3d @0x/order-utils: Move order expiration check to top in order validation. 2019-07-23 15:23:40 -07:00
Lawrence Forman
d8fd61955c @0x/contracts-test-utils: Increase deployment numbers for dummy tokens. 2019-07-23 15:23:40 -07:00
Lawrence Forman
3381ab5093 @0x/typescript-typings: Add more overloads for ethereumjs-util setLengthLeft, setLengthRight, setLength. 2019-07-23 15:23:40 -07:00
Lawrence Forman
8c2fa64c47 @0x/contracts-exchange: Remove dependency on LibAbiEncoder. 2019-07-23 15:23:40 -07:00
Lawrence Forman
12ae9fced5 @0x/contracts-exchange-forwarder: Remove dependency on LibAbiEncoder. 2019-07-23 15:23:40 -07:00
Lawrence Forman
e3bca7e7e7 @0x/exchange-libs: Remove LibAbiEncoder 2019-07-23 15:23:40 -07:00
Lawrence Forman
bca199e118 @0x/contracts-exchange: Fix Fill emit code. 2019-07-23 15:23:40 -07:00
Lawrence Forman
938ae5f27c @0x/contracts-coordinator: Remove ZRX token from coordinator tests. 2019-07-23 15:23:40 -07:00
Lawrence Forman
8aa3b535f0 @0x/contracts-exchange: Update fill order tests for arbitrary fee tokens. (Still more to do) 2019-07-23 15:23:40 -07:00
Lawrence Forman
f4bf4ee0f2 @0x/contracts-test-utils: Update types for arbitrary fee tokens. 2019-07-23 15:23:40 -07:00
Lawrence Forman
1c1ab3cd87 json-schemas: Update changelog. 2019-07-23 15:23:40 -07:00
Lawrence Forman
f5c215fe65 Update fill-scenarios for ZEIP-28 2019-07-23 15:23:40 -07:00
Lawrence Forman
9952de615a Update order-utils for ZEIP-28 2019-07-23 15:23:40 -07:00
Lawrence Forman
e1c547be98 Remove contract-wrappers contracts-exchange-forwarder and contracts-extensions from contractsPackages in root package.json 2019-07-23 15:23:40 -07:00
Lawrence Forman
7cb6795d40 @0x/contracts-exchange-libs: Add takerFeeAssetData and makerFeeAssetData to Order struct. 2019-07-23 15:23:40 -07:00
Lawrence Forman
a5f4478e20 @0x/contracts-exchange: Remove zrxAssetData from constructor and remove dependency on LibConstants.
`@0x/contracts-exchange`: Update `fillOrder()` and `matchOrders()` to settle arbitrary fees.
`@0x/contracts-exchange`: emit `Fill()` events the hard way to avoid a stack overflow.
2019-07-23 15:23:40 -07:00
Lawrence Forman
94d0db2dba In @0x/order-utils: Fix order hash tests.
In `@0x/contracts-exchange-libs`: Add fee asset datas to `LibOrder` type.
2019-07-23 15:23:40 -07:00
Amir Bandeali
64c596c922 temp 2019-07-23 15:23:40 -07:00
Amir Bandeali
e30b8999d4 Update order utils to use new order schema 2019-07-23 15:23:40 -07:00
Amir Bandeali
2f0ee84b71 Add fee assetData fields to order JSON schema 2019-07-23 15:23:40 -07:00
Amir Bandeali
c570478aaa Add fee assetData fields to OrderWithoutDomain and Order types 2019-07-23 15:23:40 -07:00
Amir Bandeali
051997acb0 Fix linting errors 2019-07-23 15:23:40 -07:00
Amir Bandeali
51ef0e1e6d Add tests for cancelOrderNoThrow and batchCancelOrdersNoThrow 2019-07-23 15:23:40 -07:00
Amir Bandeali
ed0fcf2829 Remove LibAbiEncoder 2019-07-23 15:23:40 -07:00
Amir Bandeali
2ce94b73ad Use build in abi.encode instead of LibAbiEncoder for fillOrderNoThrow 2019-07-23 15:23:40 -07:00
Amir Bandeali
ef96bff6ec Add cancelOrderNoThrow and batchCancelOrdersNoThrow 2019-07-23 15:23:40 -07:00
Greg Hysen
afc888f2ef Updated compiler.json for erc1155 and staking packages, plus removed unnecessary dependencies for staking 2019-07-23 15:23:40 -07:00
Greg Hysen
e823c2af9d Created boilerplate staking package for stake-based liquidity incentives 2019-07-23 15:23:40 -07:00
Amir Bandeali
18979f3f30 Fix linting error 2019-07-23 15:21:14 -07:00
Amir Bandeali
8bd29596c4 Rename remaining inconsistencies 2019-07-23 15:21:14 -07:00
Lawrence Forman
0cfcb6aa37 Apply suggestions from code review
Co-Authored-By: abandeali1 <abandeali1@gmail.com>
2019-07-23 15:21:14 -07:00
Amir Bandeali
6b40812e6d Fix incorrect CancelUpTo event args 2019-07-23 15:21:14 -07:00
Amir Bandeali
8af253e9ab Remove accidental recursive function call in TestLibs contract 2019-07-23 15:21:14 -07:00
Amir Bandeali
6763bce627 Add _ to remaining internal/private functions 2019-07-23 15:21:14 -07:00
Amir Bandeali
3217c1e11f Remove unused SafeMath functions 2019-07-23 15:21:14 -07:00
Amir Bandeali
6ce3e18831 Remove deprecated error libs 2019-07-23 15:21:14 -07:00
Amir Bandeali
3e461ac2e5 Rename internal and private functions 2019-07-23 15:21:14 -07:00
Lawrence Forman
25e2baaea7 Fix linter errors. 2019-07-23 15:21:14 -07:00
Lawrence Forman
6696a714f0 Disable test-contracts-geth CI job until our geth docker is updated to constantinople. 2019-07-23 15:21:14 -07:00
Lawrence Forman
46af2ffcea In @0x/contracts-exchange: Merge new transaction tests from rebase. 2019-07-23 15:21:14 -07:00
Lawrence Forman
e5b3a82112 In @0x/contracts-utils and @0x/contracts-exchange: Hardcode rich revert selector constants. 2019-07-23 15:21:14 -07:00
Lawrence Forman
9af51aaca1 Add PRs to changelogs. 2019-07-23 15:21:14 -07:00
Lawrence Forman
3bacf09710 Update changelogs 2019-07-23 15:21:14 -07:00
Lawrence Forman
61bdbd2d74 Rebased against 3.0.
Run prettier/linter.
2019-07-23 15:21:14 -07:00
Lawrence Forman
a1293f160f In @0x/contracts-exchange: Remove only from lib_exchange_rich_error_decoder tests. 2019-07-23 15:21:14 -07:00
Lawrence Forman
847503bff1 In @0x/contracts-exchange: Add more tests for LibExchangeRichErrorDecoder. 2019-07-23 15:21:14 -07:00
Lawrence Forman
576242551f In @0x/contracts-exchange: Add more tests for LibExchangeRichErrorDecoder. 2019-07-23 15:21:14 -07:00
Lawrence Forman
fdb6bee65f In @0x/contracts-exchange: Add tests for LibExchangeRichErrorDecoder. 2019-07-23 15:21:14 -07:00
Lawrence Forman
a2846faa61 Move @0x/rich-reverts-decoder into @0x/contracts-exchange/contracts/src/libs/LibExchangeRichErrorDecoder. 2019-07-23 15:21:14 -07:00
Lawrence Forman
a32544b53a In @0x/contracts-rich-reverts-decoder: Add more decoders. 2019-07-23 15:21:14 -07:00
Lawrence Forman
9b093dab0a In @0x/contracts-rich-reverts: Move to a single contract file. Inherit from @0x/contracts-exchange/.../MExchangeRichErrorTypes.sol. 2019-07-23 15:21:14 -07:00
Lawrence Forman
84d433fa06 Update gitignore to ignore @0x/contracts/rich-reverts-decoder generated artifacts. 2019-07-23 15:21:14 -07:00
Lawrence Forman
e24b8947e0 In @0x/contracts-exchange: Pull types and constants from MExchangeRichErrors into MExchangeRichErrorTypes.
In `@0x/contracts-utils`: Pull types and constants from `MRichErrors` into `MRichErrorTypes`.
2019-07-23 15:21:14 -07:00
Lawrence Forman
7835c6e20c Create @0x/contracts-rich-reverts-decoder. 2019-07-23 15:21:14 -07:00
Lawrence Forman
d942c47f08 In @0x/contracts-exchange: Change parameter order and naming of some rich revert errors.
In `@0x/order-utils`: Change parameter order for `OrderStatusError`.
2019-07-23 15:21:14 -07:00
Lawrence Forman
fdaee1375c In @0x/contracts-exchange: Update tests for rich reverts 2019-07-23 15:21:14 -07:00
Lawrence Forman
d25a510291 In @0x/contracts-exchange: upgrading tests... 2019-07-23 15:21:14 -07:00
Lawrence Forman
0cb8586f68 Unpin coordinator deps.
Update coordinator tests for new tooling.
Remove unecessary `chainId` parameter in `eip712_utils.createCoordinatorApprovalTypeData`
2019-07-23 15:21:14 -07:00
Amir Bandeali
e42a0979bc Add return natspec to all MixinTransaction functions 2019-07-23 15:21:14 -07:00
Amir Bandeali
f1a78682aa Add batch fill method tests 2019-07-23 15:21:14 -07:00
Amir Bandeali
dc4bfde76d Fix linting errors 2019-07-23 15:21:14 -07:00
Amir Bandeali
e717625f86 Add batchExecuteTransactions tests 2019-07-23 15:21:14 -07:00
Amir Bandeali
41444e7ede Refactor transaction tests to iclude more combinations and to cover all revert cases 2019-07-23 15:21:14 -07:00
Amir Bandeali
ac9247195b Don't use exchangeDataEncoder as default for functions that don't involve orders 2019-07-23 15:21:14 -07:00
Amir Bandeali
fc2a59ceaa Update imports in tests 2019-07-23 15:21:13 -07:00
Amir Bandeali
72f4b216c1 Move exchange specific types. constants, and utils into exchange package 2019-07-23 15:21:13 -07:00
Amir Bandeali
d373f5488a Add functions with mutex to ReentrantERC20Token and update IExchange with missing function 2019-07-23 15:19:33 -07:00
Amir Bandeali
24906138c7 Make preSign compatible with executeTransaction 2019-07-23 15:19:33 -07:00
Amir Bandeali
f4b3b69b2f Move constants and exchangeDataEncoder into test-utils package 2019-07-23 15:19:33 -07:00
Amir Bandeali
e80abad19a Add batchExecuteTransaction 2019-07-23 15:18:26 -07:00
Amir Bandeali
c9c228ffdd Add return data to executeTransaction 2019-07-23 15:18:26 -07:00
Amir Bandeali
6fc30d31bf Fix missed conflicts and rebuild 2019-07-23 15:18:26 -07:00
Lawrence Forman
0bcd47b394 Add OrderValidator and WalletOrderValidator signature strategies to Exchange (#1774)
* In `@0x/contracts-exchange`: Add `SignatureType.OrderValidator` support to contracts and refactor signature validation functions.

* In `@0x/types`: Add `SignatureType.OrderValidator` and `RevertReason.InappropriateSignature`.

* In `@0x/contracts-exchange`: Fix contracts and update tests for `SignatureType.OrderValidator`.

* Ran prettier/linter

* Update changelogs

* In `@0x/order-utils`: Add `SignatureOrderValidatorError` to `ExchangeRevertErrors`.

* In `@0x/contracts-exchange`: Add `SignatureOrderValidatorError` rich revert. Fix rebase issues. Rename `IValidator.isValidOrder` to `IValidator.isValidOrderSignature`.

* In `@0x/contracts-exchange`: Add revert test cases for `OrderValidator` signature type.

* In `@0x/order-utils`: Update changelog.

* In `@0x/contracts-exchange`: Split off `SignatureType.OrderValidator` scheme into its own interface and registry.

* In `@0x/types`: Add `SignatureType.WalletOrderValidator`.

* In `@0x/order-utils`: Add `SignatureWalletOrderValidatorError`.

* In `@0x/contracts-exchange`: Add `SignatureType.WalletOrderValidator` support.

* Ran prettier

* In `@0x/types`: Remove `RevertReason.WalletOrderValidator`.

* Update/fix changelogs in `@0x/contracts-exchange`, `@0x/order-utils`, and `@0x/types`.

* In `@0x/contracts-exchange`: Make `isValidOrderSignature` `external` instead of `public`.

* In `@0x/contracts-exchange`: Change `isValidOrderSignature` back to `public` because passing `calldata` to internal functions isn't supported.
2019-07-23 15:18:26 -07:00
Lawrence Forman
c24bb139dd In @0x/contracts-exchange: Change validator/wallet return value test to == 1 instead of != 0. 2019-07-23 15:17:57 -07:00
Lawrence Forman
eb00ff05a8 Ran prettier/linter 2019-07-23 15:17:57 -07:00
Lawrence Forman
a7fe47f295 In @0x/contracts-exchange: Add SignatureWalletError and SignatureValidatorError rich reverts.
In `@0x/contracts-exchange`: Change `AssetProxyTransferError` to accept a `revertData` bytes instead of a `revertReason` string.
In `@0x/contracts-exchange`: Aadd `contracts/test/TestRevertReceiver.sol` for testing that validator/wallet reverts are properly wrapped.
2019-07-23 15:17:57 -07:00
Lawrence Forman
2a6f02c764 In @0x/order-utils: Add SignatureWalletError, SignatureValidatorError to ExchangeRevertErrors. Update AssetProxyTransferError to accept arbitrary errorData bytes instead of a revertReason string. 2019-07-23 15:17:57 -07:00
Amir Bandeali
1b2ff1f9ae Update contracts/exchange/contracts/src/MixinSignatureValidator.sol
Co-Authored-By: dorothy-zbornak <lawrence@0xproject.com>
2019-07-23 15:17:57 -07:00
Lawrence Forman
7de9a36d01 In @0x/contracts-exchange: Fix comments in MixinSignatureValidator.sol. 2019-07-23 15:17:57 -07:00
Lawrence Forman
cfa8796b18 In @0x/contracts-exchange: Fix line count linter error. 2019-07-23 15:17:57 -07:00
Lawrence Forman
3c88ede02c In @0x/order-utils: Add TransactionSignatureError to ExchangeRevertErrors.
In `@0x/contracts-exchange`: Add `TransactionSignatureError`, supplanting `TransactionErrorCodes.BAD_SIGNATURE`, and associated test.
2019-07-23 15:17:57 -07:00
Lawrence Forman
a0223835b8 In @0x/order-utils: Add signerAddress and signature to ExchangeRevertErrors.SignatureError.
In `@0x/contracts-exchange`: Add `signerAddress` and `signature` to `SignatureError` reverts.
2019-07-23 15:17:56 -07:00
Lawrence Forman
ac18359410 Switch order of parameters in some rich reverts for easier dirty parsing. 2019-07-23 15:17:56 -07:00
Lawrence Forman
8194e3d3c5 In @0x/contracts-exchange: More efficient revert string extraction in MixinAssetProxyDispatcher.sol 2019-07-23 15:17:56 -07:00
Lawrence Forman
440c4fe9b9 In @0x/contracts-utils switch from encodePacked to encodeWithSelector in RichErrors.StandardError 2019-07-23 15:17:56 -07:00
Lawrence Forman
e54f5d563f In @0x/contracts-utils add natspec comments RichErrors.StandardError 2019-07-23 15:17:56 -07:00
Lawrence Forman
5781ab5436 Add PRs to changelogs 2019-07-23 15:17:56 -07:00
Lawrence Forman
f8009dbb27 In @0x/contracts-test-utils: Update CHANGELOG 2019-07-23 15:17:56 -07:00
Lawrence Forman
15efe3ae31 Fix linter errors 2019-07-23 15:17:56 -07:00
Lawrence Forman
991348bbbe In @0x/contracts-extensions: Upgrade tests for rich reverts 2019-07-23 15:17:56 -07:00
Lawrence Forman
233336ea16 Ran prettier and linter 2019-07-23 15:17:56 -07:00
Lawrence Forman
20d8c1b51a In @0x/contracts-exchange: Update tests for rich reverts 2019-07-23 15:17:56 -07:00
Lawrence Forman
06499f2155 In @0x/contract-wrappers: Update tests 2019-07-23 15:17:56 -07:00
Lawrence Forman
5b1d9396d7 In @0x/order-utils: Rename Exchange RevertError error codes. 2019-07-23 15:17:56 -07:00
Lawrence Forman
633c5d5938 In @0x/utils add encode() method to RevertError 2019-07-23 15:17:56 -07:00
Lawrence Forman
2e846159a8 In @0x/dev-utils: swap order of equality check in RevertError chai helper from actual.equals(expected) to expected.equals(actual). 2019-07-23 15:17:56 -07:00
Lawrence Forman
4408604c2d In @0x/contracts-exchange: upgrading tests... 2019-07-23 15:17:56 -07:00
Lawrence Forman
15db5c8059 In @0x/contracts-exchange: Fix busted TestAssetProxyDispatcher.sol 2019-07-23 15:17:56 -07:00
Lawrence Forman
53121b1dd4 In @0x/order-utils: add AssetProxyTransferError Exchange RevertError 2019-07-23 15:17:56 -07:00
Lawrence Forman
c36dff6354 In @0x/contracts-exchange: Fix dispatchTransferFrom so it preserves the assetData. 2019-07-23 15:17:56 -07:00
Lawrence Forman
94a91ed5c8 In @0x/dev-utils: Tweak equality assertion failure actual and expected rendering to be more readable 2019-07-23 15:17:56 -07:00
Lawrence Forman
162a812189 In @0x/typescript-typings: Add types for @0x/dev-utils chai helpers in types/@0x.
In `@0x/dev-utils`: remove global typescript types for chai helpers in lieu of defining them in `@0x/typescript-typings`
2019-07-23 15:17:56 -07:00
Lawrence Forman
f06f0785f1 In @0x/contracts-test-utils: Inherit OrderStatus from @0x/types 2019-07-23 15:17:28 -07:00
Lawrence Forman
1aae68c614 In @0x/dev-utils: Break out RevertError helper code into a separate file from chai_setup.ts.
In `@0x/dev-utils`: Add chai support for ganache and geth transaction reverts.
2019-07-23 15:17:28 -07:00
Lawrence Forman
703a0fde3c In @0x/utils: Add AnyRevertError type that matches with any revert error 2019-07-23 15:17:28 -07:00
Lawrence Forman
abb71cd074 In @0x/order-utils: Rename ExchangeErrors to ExchangeRevertErrors. 2019-07-23 15:17:28 -07:00
Lawrence Forman
79cf9156eb In @0x/contracts-test-utils add generatePseudoRandomOrderHash() to orderUtils. 2019-07-23 15:16:49 -07:00
Lawrence Forman
3a6664282c In @0x/contracts-exchange: fix contract bugs introduced by changes 2019-07-23 15:16:49 -07:00
Lawrence Forman
e00ac37cb2 In @0x/dev-utils fix the RevertError chai helper's equal override not passing all arguments to previous handler.
In `@0x/dev-utils` add more `RevertError` chai helper tests for backwards compatibility with `rejectedWith`.
In `@0x/dev-utils` instead of overriding `rejectedWith`, add a new method `revertWith`.
In `@0x/dev-utils` clean up the code for the `RevertError` chai helper.
2019-07-23 15:16:49 -07:00
Lawrence Forman
6583ac9ba1 Make @0x/base-contract _throwIfRevertWithReasonCallResult decode and throw RevertErrors.
Remove no longer necessary dependency on `ethers.js` in `@0x/base-contract`.
2019-07-23 15:16:49 -07:00
Lawrence Forman
42963ea77d Use new RevertError nomenclature.
Tweak `RevertError` coercion in chai helper.
Add more `RevertError` chai helper tests.
2019-07-23 15:15:17 -07:00
Lawrence Forman
6231724f49 Rename RichRevertReason to RevertError.
Rename `StandardError` to `StringRevertError`.
Rename `RichRevertAbi` to `RevertErrorAbi`.
Make `RevertError` extend `Error` so it can be thrown.
Add `RevertError` tests.
2019-07-23 15:15:17 -07:00
Lawrence Forman
5b25eb4fbd Fix linter errors. 2019-07-23 15:15:17 -07:00
Lawrence Forman
565cc7b3c8 Ran prettier 2019-07-23 15:15:17 -07:00
Lawrence Forman
71dc2690aa Export StandardError from @0x/utils 2019-07-23 15:15:17 -07:00
Lawrence Forman
3accd48ea8 Remove chai plugin dependencies from @0x/contract-test-utils and @0x/order-utils 2019-07-23 15:15:17 -07:00
Lawrence Forman
ed78bde359 Make the chai helper for rich reverts in dev-utils more robust.
Add rich reverts chai helper tests to `dev-utils`
2019-07-23 15:14:52 -07:00
Lawrence Forman
ff1a3ab307 Add Exchange rich revert types to @0x/order-utils 2019-07-23 15:14:13 -07:00
Lawrence Forman
26643a489b Add RichRevertReason type and utilities to @0x/utils 2019-07-23 15:13:26 -07:00
Lawrence Forman
5955a541a3 In order-utils, inherit chaiSetup from @0x/dev-utils 2019-07-23 15:13:26 -07:00
Lawrence Forman
995669cccd In contract-wrappers, inherit chaiSetup from @0x/dev-utils 2019-07-23 15:13:26 -07:00
Lawrence Forman
371dc347cc Inherit chaiSetup from @0x/dev-utils 2019-07-23 15:13:26 -07:00
Lawrence Forman
9a162e5d5c Add RichRevertAbi to etherem-types 2019-07-23 15:13:26 -07:00
Lawrence Forman
9319f362bb Add chaiSetup function wtih rich revert support to @0x/dev-utils 2019-07-23 15:12:33 -07:00
Lawrence Forman
8305168bc4 Add OrderStatus to @0x/types 2019-07-23 15:12:03 -07:00
Lawrence Forman
e8ecbe32ca Convert exchange MixinWrapperFunctions to use rich reverts 2019-07-23 15:10:31 -07:00
Lawrence Forman
bc5c5050fb Convert MixinTransactions to use rich reverts 2019-07-23 15:10:31 -07:00
Lawrence Forman
8a9b9c55ce Convert MixinSignatureValidator to use rich reverts 2019-07-23 15:10:31 -07:00
Lawrence Forman
d40f343d2a Convert MixinMatchOrders to use rich reverts 2019-07-23 15:10:31 -07:00
Lawrence Forman
4954d0a018 Convert MixinExchangeCore to use rich errors. 2019-07-23 15:10:31 -07:00
Lawrence Forman
7232bef07b Change LibRichErrors to just RichErrors.
Fix compilation issues in `exchange`.
2019-07-23 15:10:31 -07:00
Lawrence Forman
7277fb3d93 Convert to use rich reverts 2019-07-23 15:10:31 -07:00
Lawrence Forman
34e0345b29 Reimplementing rich reverts in the contracts. 2019-07-23 15:10:31 -07:00
Amir Bandeali
f094e9118c Fix inconsistent pragma for ABIEncoderV2 2019-07-23 15:10:31 -07:00
Amir Bandeali
63e93d9253 Update CHANGELOGs 2019-07-23 15:10:31 -07:00
Amir Bandeali
2ec0d421f7 Cleanup LibEIP712 domain contracts 2019-07-23 15:09:46 -07:00
Amir Bandeali
8ddc890e10 Refactor BalanceThresholdFilter to use new ITransaction interface 2019-07-23 15:09:46 -07:00
Amir Bandeali
095c899913 Refactor coordinator to use new ITransactions interface 2019-07-23 15:09:46 -07:00
Amir Bandeali
e0d6a3fd1d Refactor executeTransaction to take ZeroExTransaction struct as input 2019-07-23 15:09:46 -07:00
Amir Bandeali
308ff15adc Refactor EIP712 libraries 2019-07-23 15:09:46 -07:00
Lawrence Forman
c195629a77 Update changelogs. 2019-07-23 15:08:58 -07:00
Lawrence Forman
6af5a67a17 Fix import order in contracts/test-utils 2019-07-23 15:08:30 -07:00
Lawrence Forman
0b38289703 Ran prettier 2019-07-23 15:08:30 -07:00
Lawrence Forman
041bf9b54e Rename orderWithoutExchangeAddress -> orderWithoutDomain in contracts/exchange tests. 2019-07-23 15:08:30 -07:00
Lawrence Forman
5a6cf2b690 Rename orderWithoutExchangeAddress -> orderWithoutDomain in contracts/test-utils/.../formatters.ts. 2019-07-23 15:08:30 -07:00
Lawrence Forman
2e44bb6085 Fix removing domain and signature fields from order 2019-07-23 15:08:30 -07:00
Lawrence Forman
b8f056b82f Update coordinator, exchange-forwarder, exchange-libs, exchange, and extensions contract tests to use new order and transaction structure 2019-07-23 15:08:00 -07:00
Lawrence Forman
259b463b73 Update contracts/test-utils to use new Order structure and domain schema. 2019-07-23 15:08:00 -07:00
Lawrence Forman
4aae7348d1 Update fill-scenarios, contract-wrappers, contract-artifacts, abi-gen-wrappers to use new domain schema and Order format. 2019-07-23 15:08:00 -07:00
Lawrence Forman
665942a8c9 Update order-utils package for new Order structure 2019-07-23 15:04:46 -07:00
Lawrence Forman
dc9a26ae8a Update packages/utils tests to conform to new domain schema 2019-07-23 15:04:46 -07:00
Lawrence Forman
55f3322576 Rename eip712domain field in Order and ZeroExTransaction to just domain. 2019-07-23 15:04:46 -07:00
Lawrence Forman
376f068719 Add eip712DomainSchema to json-schemas.
Add required field `domain` to `order` and `zeroExTransaction` schemas.
2019-07-23 15:04:46 -07:00
Lawrence Forman
3688956ee5 Switch eip712 domain field verifyingContract to verifyingContractAddress 2019-07-23 15:04:46 -07:00
Lawrence Forman
53b1037a33 contracts/exchange-libs/contracts/test/TestLibs now inherits from LibEIP712ExchangeDomain rather than LibEIP712 2019-07-23 15:04:46 -07:00
Lawrence Forman
2b5cd02bd9 Remove deleted coordinator test contracts that accidentally survived the rebase 2019-07-23 15:04:46 -07:00
Lawrence Forman
e5fed57b8b Make contracts/exchange-libs/.../LibEIP712.sol stateless 2019-07-23 15:04:46 -07:00
Lawrence Forman
a0b1f3efa2 Fix typo in exchange-libs test. 2019-07-23 15:04:46 -07:00
Lawrence Forman
f7fb1225d2 Add more LibEIP712 tests to exchange-libs 2019-07-23 15:04:46 -07:00
Lawrence Forman
b380952ff9 Add test to exchange-libs to ensure that a different chainId results in a different order hash. 2019-07-23 15:04:46 -07:00
Lawrence Forman
2524e7eea3 Update changelogs 2019-07-23 15:04:46 -07:00
Lawrence Forman
32460f00f8 Add chainId to order json-schemas tests. 2019-07-23 14:59:31 -07:00
Lawrence Forman
d58d7f457d Update coordinator decodeOrdersFromFillData tests to include chainId 2019-07-23 14:59:31 -07:00
Lawrence Forman
232a43f34f Update contract-wrappers tests. 2019-07-23 14:59:31 -07:00
Lawrence Forman
94f5a039d2 Update migrations for coordinator and exchange contracts. 2019-07-23 14:59:31 -07:00
Lawrence Forman
7a4ae74727 Add chainId to order JSON schema 2019-07-23 14:59:31 -07:00
Lawrence Forman
1295de4c78 Update generated wrappers for coordinator and exchange. 2019-07-23 14:59:31 -07:00
Lawrence Forman
77ed54f64d Ran prettier 2019-07-23 14:58:00 -07:00
Lawrence Forman
e51b425200 Unpin coordinator deps.
Update coordinator tests for new tooling.
Remove unecessary `chainId` parameter in `eip712_utils.createCoordinatorApprovalTypeData`
2019-07-23 14:58:00 -07:00
Lawrence Forman
e6aff19a0c Clearer usage of chainId constants in order-utils tests. 2019-07-23 14:58:00 -07:00
Lawrence Forman
bd06c7b343 Remove lingering invalid calls to OrderStateUtils() 2019-07-23 14:58:00 -07:00
Lawrence Forman
c096eae644 All glory to the linter gods. 2019-07-23 14:58:00 -07:00
Lawrence Forman
f77823ee24 Remove unused chainId variables in signature_utils.ts.
Obey the linter gods.
2019-07-23 14:58:00 -07:00
Lawrence Forman
35f568e346 Update exchange-forwarder tests. 2019-07-23 14:58:00 -07:00
Lawrence Forman
2d28fde24d Migrate all contract-related tooling and tests to accept a chain ID in domain separators. 2019-07-23 14:58:00 -07:00
Lawrence Forman
92fe720ac3 Remove unused LibOrder inheritance from MixinBalanceThresholdFilterCore from /contracts/extensions. 2019-07-23 14:58:00 -07:00
Lawrence Forman
74a9a13564 Unpin @0x/contracts-exchange dependency in /contracts/coordinator.
Split up EIP712 constants and functionality in `/contracts/exchange-libs` across 3, modular contracts.
Make coordinator inherit from the modular EIP712 contracts in `@0x\contracts-exchange`.
2019-07-23 14:58:00 -07:00
Lawrence Forman
7aaef5d807 Fix missing comma in LibEIP712.sol domain schema.
Add `chainId` to constructors for all test contracts deriving from `LibEIP712.sol`
2019-07-23 14:58:00 -07:00
Lawrence Forman
64b4158bad Refactor EIP712 contracts to reduce code duplication. 2019-07-23 14:58:00 -07:00
Lawrence Forman
4bbaa6b41c Update tooling/types to incorporate chainID in domain separators. 2019-07-23 14:58:00 -07:00
Lawrence Forman
964d8171dd Update exchange and coordinator contracts to incorporate chainID in their domain separators. 2019-07-23 14:58:00 -07:00
Lawrence Forman
5b1cbbf157 Fix merge artifact in contracts/exchange/CHANGELOG.json.
Correct changelog for `contracts/exchange-forwarder` after rebase.
2019-07-23 14:58:00 -07:00
Lawrence Forman
db4c29a73c Apply and mask to assembly address instruction in exchange/.../ReentrantERC20Token.sol 2019-07-23 14:58:00 -07:00
Lawrence Forman
4f73008d95 Fix typo in changelog 2019-07-23 14:58:00 -07:00
Lawrence Forman
1b73cb28f1 Update changelog 2019-07-23 14:58:00 -07:00
Lawrence
367c981642 Update changelogs 2019-07-23 14:58:00 -07:00
Lawrence Forman
3d30eb0748 Remove sol-doc from circlci 2019-07-23 14:58:00 -07:00
Lawrence Forman
34ffdad521 Manually build @0x/monorepo-scripts 2019-07-23 14:58:00 -07:00
Lawrence Forman
4f82c0c289 Edit circleci config to omit tests we aren't interested in for 3.0 2019-07-23 14:58:00 -07:00
Lawrence
fd68746dd7 Fix typo in docstring for ReentrantERC20Token.createOrders. 2019-07-23 14:54:24 -07:00
Lawrence
bec7d1265b Fix styling issues in ReentrantERC20Token.
Apply gas golfing suggestions in ReentrantERC20Token.
Describe ERC20 AssetData format in ReentrantERC20Token.
2019-07-23 14:54:24 -07:00
Lawrence
620eb2a3be Shave off an SLOAD op in ReentrancyGuard. 2019-07-23 14:54:24 -07:00
Lawrence
e6971c45c8 Update PRs in changelogs. 2019-07-23 14:54:24 -07:00
Lawrence
961cd0825c Add comment to ReentrantERC20Token about proper testing procedure 2019-07-23 14:54:24 -07:00
Lawrence
a1cb702ecb Update changelogs 2019-07-23 14:54:24 -07:00
Lawrence
befc14c980 Ran linter 2019-07-23 14:52:57 -07:00
Lawrence
ff0ad53c11 Update exchange reentrancy tests to work with lazy reentrancy detection. 2019-07-23 14:52:57 -07:00
Lawrence
cf0e57d7ce Converting tests to support new lazy reentrancy checking. 2019-07-23 14:52:57 -07:00
Lawrence Forman
9883e3ed2e Implement new ReentrancyGuard contract. 2019-07-23 14:52:57 -07:00
2066 changed files with 186208 additions and 138607 deletions

View File

@@ -23,37 +23,21 @@ jobs:
# command: npm set prefix=/home/circleci/npm && echo 'export PATH=$HOME/circleci/npm/bin:$PATH' >> /home/circleci/.bashrc
- run:
name: install-yarn
command: npm install --global yarn@1.9.4
command: npm install --global yarn@1.17.0
- run:
name: yarn
command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
- setup_remote_docker
- run: yarn build:ci:no_website
- run: yarn build:ci
- run: yarn build:ts
- save_cache:
key: repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo
- save_cache:
key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/python-contract-wrappers/generated
- store_artifacts:
path: ~/repo/packages/python-contract-wrappers/generated
- store_artifacts:
path: ~/repo/packages/abi-gen/test-cli/output
- store_artifacts:
path: ~/repo/packages/abi-gen-wrappers/generated_docs
build-website:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: cd packages/website && yarn build:prod
test-contracts-ganache:
resource_class: medium+
docker:
@@ -63,19 +47,41 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-extensions @0x/contracts-asset-proxy @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-coordinator @0x/contracts-dev-utils
test-contracts-geth:
- 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-tests @0x/contracts-staking
test-exchange-ganache-3.0:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
- image: 0xorg/devnet
working_directory: ~/repo
steps:
- restore_cache:
keys:
- 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: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
- run: yarn wsrun test:circleci @0x/contracts-exchange
test-integrations-ganache-3.0:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-integrations
test-contracts-rest-ganache-3.0:
resource_class: medium+
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-tests @0x/contracts-staking @0x/contracts-coordinator
# TODO(dorothy-zbornak): Re-enable after updating this package for
# 3.0. At that time, also remove exclusion from monorepo
# package.json's test script.
# - run: yarn wsrun test:circleci @0x/contracts-extensions
test-publish:
resource_class: medium+
docker:
@@ -86,7 +92,9 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn test:publish:circleci
- run:
command: yarn test:publish:circleci
no_output_timeout: 1800
test-doc-generation:
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
@@ -95,7 +103,9 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn test:generate_docs:circleci
- run:
command: yarn test:generate_docs:circleci
no_output_timeout: 1200
test-rest:
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
@@ -106,15 +116,23 @@ 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
# TODO (xianny): Needs to be updated for 3.0
# - run: yarn wsrun test:circleci @0x/asset-buyer
# TODO: Needs to be updated for 3.0. At that time, also remove
# exclusion from monorepo package.json's test script.
# - run: yarn wsrun test:circleci @0x/asset-swapper
- run: yarn wsrun test:circleci @0x/contract-artifacts
- run: yarn wsrun test:circleci @0x/assert
- run: yarn wsrun test:circleci @0x/base-contract
- run: yarn wsrun test:circleci @0x/connect
# TODO (xianny): Needs to be updated for 3.0
# - run: yarn wsrun test:circleci @0x/connect
- run: yarn wsrun test:circleci @0x/contract-wrappers
- run: yarn wsrun test:circleci @0x/dev-utils
- run: yarn wsrun test:circleci @0x/json-schemas
- run: yarn wsrun test:circleci @0x/order-utils
# TODO: Needs to be updated for 3.0. At that time, also remove
# exclusion from monorepo package.json's test script.
# - run: yarn wsrun test:circleci @0x/orderbook
- run: yarn wsrun test:circleci @0x/sol-compiler
- run: yarn wsrun test:circleci @0x/sol-tracing-utils
- run: yarn wsrun test:circleci @0x/sol-doc
@@ -182,20 +200,40 @@ jobs:
working_directory: ~/repo
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
- image: 0xorg/ganache-cli:2.2.2
- image: 0xorg/launch-kit-backend:74bcc39
- image: 0xorg/ganache-cli:4.4.0-beta.1
environment:
RPC_URL: http://localhost:8545
VERSION: 4.4.0-beta.1
SNAPSHOT_NAME: 0x_ganache_snapshot-v3-beta
- image: 0xorg/mesh:6.0.0-beta-0xv3
environment:
ETHEREUM_RPC_URL: 'http://localhost:8545'
ETHEREUM_NETWORK_ID: '50'
ETHEREUM_CHAIN_ID: '1337'
USE_BOOTSTRAP_LIST: 'true'
VERBOSITY: 3
PRIVATE_KEY_PATH: ''
BLOCK_POLLING_INTERVAL: '5s'
P2P_LISTEN_PORT: '60557'
command: |
sh -c "waitForGanache () { until printf 'POST /\r\nContent-Length: 26\r\n\r\n{\"method\":\"net_listening\"}' | nc localhost 8545 | grep true; do continue; done }; waitForGanache && ./mesh"
- image: 0xorg/launch-kit-backend:v3
environment:
RPC_URL: 'http://localhost:8545'
NETWORK_ID: 50
WHITELIST_ALL_TOKENS: True
FEE_RECIPIENT: '0x0000000000000000000000000000000000000001'
MAKER_FEE_UNIT_AMOUNT: 0
TAKER_FEE_UNIT_AMOUNT: 0
MESH_ENDPOINT: 'ws://localhost:60557'
command: |
sh -c "until printf 'POST /\r\nContent-Length: 26\r\n\r\n{\"method\":\"net_listening\"}' | nc localhost 8545 | grep true; do continue; done; node_modules/.bin/forever ts/lib/index.js"
sh -c "waitForMesh () { sleep 5; }; waitForMesh && node_modules/.bin/forever ts/lib/index.js"
steps:
- checkout
- restore_cache:
key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: |
cd python-packages
@@ -210,8 +248,14 @@ jobs:
- run:
command: |
cd python-packages
./parallel_without_sra_client coverage run setup.py test
./parallel coverage run setup.py test
./build_docs
- run:
command: |
# copy generated wrappers into contract_wrappers/build,
# JUST so CircleCI will persist them as build artifacts.
cd python-packages/contract_wrappers/src/zero_ex
for i in contract_wrappers/[^__]*/; do mkdir -p ../../build/$i; cp $i/__init__.py ../../build/$i; done
- save_cache:
key: coverage-python-contract-addresses-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -236,10 +280,6 @@ jobs:
key: coverage-python-sra-client-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/python-packages/sra_client/.coverage
- store_artifacts:
path: ~/repo/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py
- store_artifacts:
path: ~/repo/python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py
- store_artifacts:
path: ~/repo/python-packages/contract_addresses/build
- store_artifacts:
@@ -289,7 +329,8 @@ jobs:
- restore_cache:
key: installed-py-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
key: python-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: |
python -m ensurepip
@@ -298,6 +339,7 @@ jobs:
./install
./lint
static-tests:
resource_class: large
working_directory: ~/repo
docker:
- image: nikolaik/python-nodejs:python3.7-nodejs8
@@ -308,6 +350,7 @@ jobs:
- run: yarn lerna run lint
- run: yarn prettier:ci
- run: yarn deps_versions:ci
- run: yarn diff_md_docs:ci
- run: cd packages/0x.js && yarn build:umd:prod
- run: yarn bundlewatch
submit-coverage:
@@ -387,17 +430,15 @@ workflows:
main:
jobs:
- build
- build-website:
- test-exchange-ganache-3.0:
requires:
- build
- test-contracts-ganache:
- test-integrations-ganache-3.0:
requires:
- build
- test-contracts-rest-ganache-3.0:
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
@@ -412,13 +453,15 @@ workflows:
- build
- submit-coverage:
requires:
- test-contracts-rest-ganache-3.0
- test-exchange-ganache-3.0
- test-rest
- test-python
- static-tests-python:
requires:
- test-python
- static-tests
- test-python:
requires:
- build
- static-tests-python:
requires:
- build
# skip python tox run for now, as we don't yet have multiple test environments to support.
#- test-rest-python
# - test-rest-python

View File

@@ -13,7 +13,6 @@ contracts: ['contracts']
@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']
@@ -33,7 +32,5 @@ contracts: ['contracts']
@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']

49
.gitignore vendored
View File

@@ -40,9 +40,12 @@ build/Release
node_modules/
jspm_packages/
# Typescript v1 declaration files
# TypeScript v1 declaration files
typings/
# NVM config
.nvmrc
# Optional npm cache directory
.npm
.npmrc
@@ -75,13 +78,12 @@ TODO.md
# VSCode file
.vscode
packages/website/public/bundle*
packages/dev-tools-pages/public/bundle*
# server cli
packages/testnet-faucets/server/
# generated contract artifacts/
contracts/integrations/generated-artifacts/
contracts/staking/generated-artifacts/
contracts/coordinator/generated-artifacts/
contracts/exchange/generated-artifacts/
contracts/asset-proxy/generated-artifacts/
@@ -97,9 +99,25 @@ contracts/dev-utils/generated-artifacts/
packages/sol-tracing-utils/test/fixtures/artifacts/
python-packages/contract_artifacts/src/zero_ex/contract_artifacts/artifacts/
# generated truffle contract artifacts/
contracts/staking/build/
contracts/coordinator/build/
contracts/exchange/build/
contracts/asset-proxy/build/
contracts/multisig/build/
contracts/utils/build/
contracts/exchange-libs/build/
contracts/erc20/build/
contracts/erc721/build/
contracts/erc1155/build/
contracts/extensions/build/
contracts/exchange-forwarder/build/
contracts/dev-utils/build/
# generated contract wrappers
packages/abi-gen-wrappers/src/generated-wrappers/
packages/python-contract-wrappers/generated/
contracts/integrations/generated-wrappers/
contracts/staking/generated-wrappers/
contracts/coordinator/generated-wrappers/
contracts/exchange/generated-wrappers/
contracts/asset-proxy/generated-wrappers/
@@ -112,6 +130,7 @@ contracts/erc1155/generated-wrappers/
contracts/extensions/generated-wrappers/
contracts/exchange-forwarder/generated-wrappers/
contracts/dev-utils/generated-wrappers/
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dev_utils/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_token/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/exchange/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/asset_proxy_owner/__init__.py
@@ -120,6 +139,8 @@ python-packages/contract_wrappers/src/zero_ex/contract_wrappers/coordinator_regi
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dummy_erc20_token/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dummy_erc721_token/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/dutch_auction/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_mintable/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc1155_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc20_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/erc721_token/__init__.py
@@ -130,18 +151,13 @@ python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_validator/__in
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/i_wallet/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/multi_asset_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/order_validator/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/static_call_proxy/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/weth9/__init__.py
python-packages/contract_wrappers/src/zero_ex/contract_wrappers/zrx_token/__init__.py
# cli test output
packages/abi-gen/test-cli/output
# solc-bin in sol-compiler
packages/sol-compiler/solc_bin/
# Monorepo scripts
packages/*/scripts/
# python stuff
.eggs
.mypy_cache
@@ -152,5 +168,14 @@ __pycache__
python-packages/*/src/*.egg-info
python-packages/*/.coverage
# python keeps package-local copies of json schemas
# python keeps package-local copies of json schemas and contract addresses
python-packages/json_schemas/src/zero_ex/json_schemas/schemas
python-packages/contract_addresses/src/zero_ex/contract_addresses/addresses.json
# Doc README copy
packages/*/docs/README.md
.DS_Store
# the snapshot that gets built for migrations sure does have a ton of files
packages/migrations/0x_ganache_snapshot*

View File

@@ -1,5 +1,9 @@
lib
.nyc_output
/contracts/integrations/generated-wrappers
/contracts/integrations/generated-artifacts
/contracts/staking/generated-wrappers
/contracts/staking/generated-artifacts
/contracts/coordinator/generated-wrappers
/contracts/coordinator/generated-artifacts
/contracts/exchange/generated-wrappers
@@ -24,11 +28,23 @@ lib
/contracts/exchange-forwarder/generated-artifacts
/contracts/dev-utils/generated-wrappers
/contracts/dev-utils/generated-artifacts
/contracts/staking/build/
/contracts/coordinator/build/
/contracts/exchange/build/
/contracts/asset-proxy/build/
/contracts/multisig/build/
/contracts/utils/build/
/contracts/exchange-libs/build/
/contracts/erc20/build/
/contracts/erc721/build/
/contracts/erc1155/build/
/contracts/extensions/build/
/contracts/exchange-forwarder/build/
/contracts/dev-utils/build/
/packages/abi-gen/test-cli/output
/packages/json-schemas/schemas
/python-packages/json_schemas/src/zero_ex/json_schemas/schemas
/packages/sra-spec/public/
/packages/dev-tools-pages/ts/**/data.json
package.json
scripts/postpublish_utils.js
packages/sol-coverage/test/fixtures/artifacts
@@ -38,3 +54,4 @@ packages/sol-coverage/test/fixtures/artifacts
packages/abi-gen/test-cli/fixtures/artifacts/AbiGenDummy.json
packages/abi-gen/test-cli/fixtures/artifacts/LibDummy.json
packages/abi-gen/test-cli/fixtures/artifacts/TestLibDummy.json
packages/*/docs

View File

@@ -7,7 +7,6 @@
# Website
packages/asset-buyer/ @BMillman19 @fragosti @steveklebanoff
packages/instant/ @BMillman19 @fragosti @steveklebanoff
packages/website/ @BMillman19 @fragosti @fabioberger @steveklebanoff
# Dev tools & setup
.circleci/ @LogvinovLeon

View File

@@ -29,9 +29,9 @@ ALL PRs should be opened against `development`.
Branch names should be prefixed with `fix`, `feature` or `refactor`.
- e.g `fix/broken-wiki-link`
- e.g `fix/missing-import`
- If the PR only edits a single package, add it's name too
- e.g `fix/website/broken-wiki-link`
- e.g `fix/subproviders/missing-import`
### CHANGELOGs
@@ -55,7 +55,7 @@ If an entry without a `timestamp` already exists, this means other changes have
### Development Tooling
We strongly recommend you use the [VSCode](https://code.visualstudio.com/) text editor since most of our code is written in Typescript and it offers amazing support for the language.
We strongly recommend you use the [VSCode](https://code.visualstudio.com/) text editor since most of our code is written in TypeScript and it offers amazing support for the language.
#### Linter
@@ -89,7 +89,7 @@ A few of our coding conventions are not yet enforced by the linter/auto-formatte
1. Do not import from a project's `index.ts` (e.g import { Token } from '../src';). Always import from the source file itself.
1. Generic error variables should be named `err` instead of `e` or `error`.
1. If you _must_ cast a variable to any - try to type it back as fast as possible. (e.g., `const cw = ((zeroEx as any)._contractWrappers as ContractWrappers);`). This ensures subsequent code is type-safe.
1. Our enum conventions coincide with the recommended Typescript conventions, using capitalized keys, and all-caps snake-case values. Eg `GetStats = 'GET_STATS'`
1. Our enum conventions coincide with the recommended TypeScript conventions, using capitalized keys, and all-caps snake-case values. Eg `GetStats = 'GET_STATS'`
1. All public, exported methods/functions/classes must have associated Javadoc-style comments.
### Fix `submit-coverage` CI failure

View File

@@ -6,21 +6,16 @@
This repository is a monorepo including the 0x protocol smart contracts and numerous developer tools. Each public sub-package is independently published to NPM.
If you're developing on 0x now or are interested in using 0x infrastructure in the future, please join our [developer mailing list][dev-mailing-list-url] for updates.
[website-url]: https://0xproject.com
[whitepaper-url]: https://0xproject.com/pdfs/0x_white_paper.pdf
[dev-mailing-list-url]: http://eepurl.com/dx4cPf
[website-url]: https://0x.org
[![CircleCI](https://circleci.com/gh/0xProject/0x-monorepo.svg?style=svg&circle-token=61bf7cd8c9b4e11b132089dfcffdd1be277d1e0c)](https://circleci.com/gh/0xProject/0x-monorepo)
[![Coverage Status](https://coveralls.io/repos/github/0xProject/0x-monorepo/badge.svg?branch=development)](https://coveralls.io/github/0xProject/0x-monorepo?branch=development)
[![Discord](https://img.shields.io/badge/chat-rocket.chat-yellow.svg?style=flat)](https://chat.0xproject.com)
[![Join the chat at https://gitter.im/0xProject/Lobby](https://badges.gitter.im/0xProject/Lobby.svg)](https://gitter.im/0xProject/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Discord](https://img.shields.io/badge/chat-discord.chat-yellow.svg?style=flat)](https://discordapp.com/invite/d3FTX3M)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
## Packages
Visit our [developer portal](https://0xproject.com/docs/order-utils) for a comprehensive list of core & community maintained packages. All packages maintained with this monorepo are listed below.
Visit our [developer portal](https://0x.org/docs/tools/order-utils) for a comprehensive list of core & community maintained packages. All packages maintained with this monorepo are listed below.
### Python Packages
@@ -48,12 +43,13 @@ These packages are all under development. See [/contracts/README.md](/contracts/
| [`@0x/contracts-exchange-libs`](/contracts/exchange-libs) | [![npm](https://img.shields.io/npm/v/@0x/contracts-exchange-libs.svg)](https://www.npmjs.com/package/@0x/contracts-exchange-libs) | Protocol specific libraries used within the [`Exchange`](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#exchange) contract |
| [`@0x/contracts-extensions`](/contracts/extensions) | [![npm](https://img.shields.io/npm/v/@0x/contracts-extensions.svg)](https://www.npmjs.com/package/@0x/contracts-extensions) | Contracts that interact with and extend the functionality of the core protocol |
| [`@0x/contracts-multisig`](/contracts/multisig) | [![npm](https://img.shields.io/npm/v/@0x/contracts-multisig.svg)](https://www.npmjs.com/package/@0x/contracts-multisig) | Various implementations of multisignature wallets, including the [`AssetProxyOwner`](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#assetproxyowner) contract that has permissions to upgrade the protocol |
| [`@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-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) |
| [`@0x/contracts-staking`](/contracts/staking) | [![npm](https://img.shields.io/npm/v/@0x/contracts-staking.svg)](https://www.npmjs.com/package/@0x/contracts-staking) | Implements the stake-based liquidity incentives defined by [`ZEIP-31`](https://github.com/0xProject/ZEIPs/issues/31) |
### Typescript/Javascript Packages
### TypeScript/Javascript Packages
#### 0x-specific packages
@@ -97,7 +93,6 @@ These packages are all under development. See [/contracts/README.md](/contracts/
| [`@0x/assert`](/packages/assert) | [![npm](https://img.shields.io/npm/v/@0x/assert.svg)](https://www.npmjs.com/package/@0x/assert) | Type and schema assertions used by our packages |
| [`@0x/base-contract`](/packages/base-contract) | [![npm](https://img.shields.io/npm/v/@0x/base-contract.svg)](https://www.npmjs.com/package/@0x/base-contract) | BaseContract used by auto-generated `abi-gen` wrapper contracts |
| [`@0x/dev-utils`](/packages/dev-utils) | [![npm](https://img.shields.io/npm/v/@0x/dev-utils.svg)](https://www.npmjs.com/package/@0x/dev-utils) | Dev utils to be shared across 0x packages |
| [`@0x/fill-scenarios`](/packages/fill-scenarios) | [![npm](https://img.shields.io/npm/v/@0x/fill-scenarios.svg)](https://www.npmjs.com/package/@0x/fill-scenarios) | 0x order fill scenario generator |
#### Private Packages
@@ -105,11 +100,10 @@ These packages are all under development. See [/contracts/README.md](/contracts/
| -------------------------------------------------- | -------------------------------------------------------------------------------- |
| [`@0x/instant`](/packages/instant) | A free and flexible way to offer simple crypto purchasing in any app or website. |
| [`@0x/testnet-faucets`](/packages/testnet-faucets) | A faucet micro-service that dispenses test ERC20 tokens or Ether |
| [`@0x/website`](/packages/website) | 0x website |
## Usage
Node version >= 6.12 is required.
Node version 6.x or 8.x is required.
Most of the packages require additional typings for external dependencies.
You can include those by prepending the `@0x/typescript-typings` package to your [`typeRoots`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) config.
@@ -138,6 +132,8 @@ Then install dependencies
yarn install
```
You will also need to have Python 3 installed, in order to build and run the tests of `abi-gen`'s command-line interface, which is integrated with the yarn build, yarn test, and yarn lint commands described below. More specifically, your local pip should resolve to the Python 3 version of pip, not a Python 2.x version.
### Build
To build all packages:

View File

@@ -0,0 +1,2 @@
# solhint can't parse `abi.decode` syntax.
contracts/src/ERC1155Proxy.sol

View File

@@ -1,4 +1,79 @@
[
{
"version": "2.3.0-beta.1",
"changes": [
{
"note": "ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract",
"pr": 2034
}
],
"timestamp": 1573159180
},
{
"version": "2.3.0-beta.0",
"changes": [
{
"note": "Disallow the zero address from being made an authorized address in MixinAuthorizable, and created an archive directory that includes an old version of Ownable",
"pr": 2019
},
{
"note": "Remove `LibAssetProxyIds` contract",
"pr": 2055
},
{
"note": "Compile and export all contracts, artifacts, and wrappers by default",
"pr": 2055
},
{
"note": "Remove unused dependency on IAuthorizable in IAssetProxy",
"pr": 1910
},
{
"note": "Add `ERC20BridgeProxy`",
"pr": 2220
},
{
"note": "Add `Eth2DaiBridge`",
"pr": 2221
},
{
"note": "Add `UniswapBridge`",
"pr": 2233
},
{
"note": "Replaced `SafeMath` with `LibSafeMath`",
"pr": 2254
}
],
"timestamp": 1570135330
},
{
"timestamp": 1568744790,
"version": "2.2.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1567521715,
"version": "2.2.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1566446343,
"version": "2.2.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1565296576,
"version": "2.2.5",
@@ -96,6 +171,18 @@
{
"note": "Update tests to use contract-built-in `awaitTransactionSuccessAsync`",
"pr": 1797
},
{
"note": "Make `ERC721Wrapper.setApprovalForAll()` take an owner address instead of a token ID",
"pr": 1819
},
{
"note": "Automatically set unlimited proxy allowances in `ERC721.setBalancesAndAllowancesAsync()`",
"pr": 1819
},
{
"note": "Add `setProxyAllowanceForAllAsync()` to `ERC1155ProxyWrapper`.",
"pr": 1819
}
],
"timestamp": 1557507213

View File

@@ -5,6 +5,33 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.3.0-beta.1 - _November 7, 2019_
* ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract (#2034)
## v2.3.0-beta.0 - _October 3, 2019_
* Disallow the zero address from being made an authorized address in MixinAuthorizable, and created an archive directory that includes an old version of Ownable (#2019)
* Remove `LibAssetProxyIds` contract (#2055)
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
* Remove unused dependency on IAuthorizable in IAssetProxy (#1910)
* Add `ERC20BridgeProxy` (#2220)
* Add `Eth2DaiBridge` (#2221)
* Add `UniswapBridge` (#2233)
* Replaced `SafeMath` with `LibSafeMath` (#2254)
## v2.2.8 - _September 17, 2019_
* Dependencies updated
## v2.2.7 - _September 3, 2019_
* Dependencies updated
## v2.2.6 - _August 22, 2019_
* Dependencies updated
## v2.2.5 - _August 8, 2019_
* Dependencies updated
@@ -46,6 +73,9 @@ CHANGELOG
## v2.1.2 - _May 10, 2019_
* Update tests to use contract-built-in `awaitTransactionSuccessAsync` (#1797)
* Make `ERC721Wrapper.setApprovalForAll()` take an owner address instead of a token ID (#1819)
* Automatically set unlimited proxy allowances in `ERC721.setBalancesAndAllowancesAsync()` (#1819)
* Add `setProxyAllowanceForAllAsync()` to `ERC1155ProxyWrapper`. (#1819)
## v2.1.1 - _April 11, 2019_

View File

@@ -1,6 +1,6 @@
## AssetProxy
This package contains the implementations of all of the [`AssetProxy`](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#assetproxy) contracts available within the 0x protocol. These contracts are responsible for decoding the `assetData` sent to them and performing the actual transfer of assets. 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.
This package contains the implementations of all of the [`AssetProxy`](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#assetproxy) contracts available within the 0x protocol. These contracts are responsible for decoding the `assetData` sent to them and performing the actual transfer of assets. Addresses of the deployed contracts can be found in this 0x [guide](https://0x.org/docs/guides/0x-cheat-sheet) or the [DEPLOYS](./DEPLOYS.json) file within this package.
## Installation
@@ -12,7 +12,7 @@ npm install @0x/contracts-asset-proxy --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).
A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0x.org/docs/guides/bug-bounty-program).
## Contributing

View File

@@ -22,17 +22,5 @@
]
}
}
},
"contracts": [
"src/ERC1155Proxy.sol",
"src/ERC20Proxy.sol",
"src/ERC721Proxy.sol",
"src/MixinAuthorizable.sol",
"src/MultiAssetProxy.sol",
"src/StaticCallProxy.sol",
"src/interfaces/IAssetData.sol",
"src/interfaces/IAssetProxy.sol",
"src/interfaces/IAuthorizable.sol",
"test/TestStaticCallTarget.sol"
]
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,16 +16,16 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/Ownable.sol";
import "./mixins/MAssetProxyDispatcher.sol";
import "./interfaces/IAssetProxy.sol";
import "../archive/Ownable.sol";
import "../src/interfaces/IAssetProxy.sol";
import "../src/interfaces/IAssetProxyDispatcher.sol";
contract MixinAssetProxyDispatcher is
Ownable,
MAssetProxyDispatcher
IAssetProxyDispatcher
{
// Mapping from Asset Proxy Id's to their respective Asset Proxy
mapping (bytes4 => address) public assetProxies;
@@ -69,7 +69,7 @@ contract MixinAssetProxyDispatcher is
/// @param from Address to transfer token from.
/// @param to Address to transfer token to.
/// @param amount Amount of token to transfer.
function dispatchTransferFrom(
function _dispatchTransferFrom(
bytes memory assetData,
address from,
address to,
@@ -84,7 +84,7 @@ contract MixinAssetProxyDispatcher is
assetData.length > 3,
"LENGTH_GREATER_THAN_3_REQUIRED"
);
// Lookup assetProxy. We do not use `LibBytes.readBytes4` for gas efficiency reasons.
bytes4 assetProxyId;
assembly {
@@ -100,10 +100,10 @@ contract MixinAssetProxyDispatcher is
assetProxy != address(0),
"ASSET_PROXY_DOES_NOT_EXIST"
);
// We construct calldata for the `assetProxy.transferFrom` ABI.
// The layout of this calldata is in the table below.
//
//
// | Area | Offset | Length | Contents |
// | -------- |--------|---------|-------------------------------------------- |
// | Header | 0 | 4 | function selector |
@@ -127,12 +127,12 @@ contract MixinAssetProxyDispatcher is
// `cdEnd` is the end of the calldata for `assetProxy.transferFrom`.
let cdEnd := add(cdStart, add(132, dataAreaLength))
/////// Setup Header Area ///////
// This area holds the 4-byte `transferFromSelector`.
// bytes4(keccak256("transferFrom(bytes,address,address,uint256)")) = 0xa85e59e4
mstore(cdStart, 0xa85e59e400000000000000000000000000000000000000000000000000000000)
/////// Setup Params Area ///////
// Each parameter is padded to 32-bytes. The entire Params Area is 128 bytes.
// Notes:
@@ -142,7 +142,7 @@ contract MixinAssetProxyDispatcher is
mstore(add(cdStart, 36), and(from, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(cdStart, 68), and(to, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(cdStart, 100), amount)
/////// Setup Data Area ///////
// This area holds `assetData`.
let dataArea := add(cdStart, 132)
@@ -159,7 +159,7 @@ contract MixinAssetProxyDispatcher is
assetProxy, // call address of asset proxy
0, // don't send any ETH
cdStart, // pointer to start of input
sub(cdEnd, cdStart), // length of input
sub(cdEnd, cdStart), // length of input
cdStart, // write output over input
512 // reserve 512 bytes for output
)

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,15 +16,15 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/Ownable.sol";
import "./mixins/MAuthorizable.sol";
import "../archive/Ownable.sol";
import "../src/interfaces/IAuthorizable.sol";
contract MixinAuthorizable is
Ownable,
MAuthorizable
IAuthorizable
{
/// @dev Only authorized addresses can invoke functions with this modifier.
modifier onlyAuthorized {

View File

@@ -0,0 +1,33 @@
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/interfaces/IOwnable.sol";
contract Ownable is
IOwnable
{
address public owner;
constructor ()
public
{
owner = msg.sender;
}
modifier onlyOwner() {
require(
msg.sender == owner,
"ONLY_CONTRACT_OWNER"
);
_;
}
function transferOwnership(address newOwner)
public
onlyOwner
{
if (newOwner != address(0)) {
owner = newOwner;
}
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -19,18 +19,18 @@
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-utils/contracts/src/SafeMath.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol";
import "./MixinAuthorizable.sol";
import "../archive/MixinAuthorizable.sol";
import "./interfaces/IAssetProxy.sol";
contract ERC1155Proxy is
MixinAuthorizable,
SafeMath,
IAssetProxy
{
using LibBytes for bytes;
using LibSafeMath for uint256;
// Id of this proxy.
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC1155Assets(address,uint256[],uint256[],bytes)"));
@@ -69,9 +69,9 @@ contract ERC1155Proxy is
for (uint256 i = 0; i != length; i++) {
// We write the scaled values to an unused location in memory in order
// to avoid copying over `ids` or `data`. This is possible if they are
// identical to `values` and the offsets for each are pointing to the
// identical to `values` and the offsets for each are pointing to the
// same location in the ABI encoded calldata.
scaledValues[i] = safeMul(values[i], amount);
scaledValues[i] = values[i].safeMul(amount);
}
// Execute `safeBatchTransferFrom` call

View File

@@ -0,0 +1,126 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "@0x/contracts-utils/contracts/src/Authorizable.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "./interfaces/IAssetProxy.sol";
import "./interfaces/IERC20Bridge.sol";
contract ERC20BridgeProxy is
IAssetProxy,
Authorizable
{
using LibBytes for bytes;
using LibSafeMath for uint256;
// @dev Id of this proxy. Also the result of a successful bridge call.
// bytes4(keccak256("ERC20Bridge(address,address,bytes)"))
bytes4 constant private PROXY_ID = 0xdc1600f3;
/// @dev Calls a bridge contract to transfer `amount` of ERC20 from `from`
/// to `to`. Asserts that the balance of `to` has increased by `amount`.
/// @param assetData Abi-encoded data for this asset proxy encoded as:
/// abi.encodeWithSelector(
/// bytes4 PROXY_ID,
/// address tokenAddress,
/// address bridgeAddress,
/// bytes bridgeData
/// )
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
function transferFrom(
bytes calldata assetData,
address from,
address to,
uint256 amount
)
external
onlyAuthorized
{
// Extract asset data fields.
(
address tokenAddress,
address bridgeAddress,
bytes memory bridgeData
) = abi.decode(
assetData.sliceDestructive(4, assetData.length),
(address, address, bytes)
);
// Remember the balance of `to` before calling the bridge.
uint256 balanceBefore = balanceOf(tokenAddress, to);
// Call the bridge, who should transfer `amount` of `tokenAddress` to
// `to`.
bytes4 success = IERC20Bridge(bridgeAddress).bridgeTransferFrom(
tokenAddress,
from,
to,
amount,
bridgeData
);
// Bridge must return the proxy ID to indicate success.
require(success == PROXY_ID, "BRIDGE_FAILED");
// Ensure that the balance of `to` has increased by at least `amount`.
require(
balanceBefore.safeAdd(amount) <= balanceOf(tokenAddress, to),
"BRIDGE_UNDERPAY"
);
}
/// @dev Gets the proxy id associated with this asset proxy.
/// @return proxyId The proxy id.
function getProxyId()
external
pure
returns (bytes4 proxyId)
{
return PROXY_ID;
}
/// @dev Retrieves the balance of `owner` for this asset.
/// @return balance The balance of the ERC20 token being transferred by this
/// asset proxy.
function balanceOf(bytes calldata assetData, address owner)
external
view
returns (uint256 balance)
{
(address tokenAddress) = abi.decode(
assetData.sliceDestructive(4, assetData.length),
(address)
);
return balanceOf(tokenAddress, owner);
}
/// @dev Retrieves the balance of `owner` given an ERC20 address.
/// @return balance The balance of the ERC20 token for `owner`.
function balanceOf(address tokenAddress, address owner)
private
view
returns (uint256 balance)
{
return IERC20Token(tokenAddress).balanceOf(owner);
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,9 +16,9 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "./MixinAuthorizable.sol";
import "../archive/MixinAuthorizable.sol";
contract ERC20Proxy is
@@ -26,9 +26,9 @@ contract ERC20Proxy is
{
// Id of this proxy.
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC20Token(address)"));
// solhint-disable-next-line payable-fallback
function ()
function ()
external
{
assembly {
@@ -117,13 +117,13 @@ contract ERC20Proxy is
// * The "token address" is offset 32+4=36 bytes into "assetData" (tables 1 & 2).
// [tokenOffset = assetDataOffsetFromHeader + 36 = calldataload(4) + 4 + 36]
let token := calldataload(add(calldataload(4), 40))
/////// Setup Header Area ///////
// This area holds the 4-byte `transferFrom` selector.
// Any trailing data in transferFromSelector will be
// overwritten in the next `mstore` call.
mstore(0, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
/////// Setup Params Area ///////
// We copy the fields `from`, `to` and `amount` in bulk
// from our own calldata to the new calldata.
@@ -147,7 +147,7 @@ contract ERC20Proxy is
// If the token does return data, we require that it is a single
// nonzero 32 bytes value.
// So the transfer succeeded if the call succeeded and either
// returned nothing, or returned a non-zero 32 byte value.
// returned nothing, or returned a non-zero 32 byte value.
success := and(success, or(
iszero(returndatasize),
and(
@@ -158,7 +158,7 @@ contract ERC20Proxy is
if success {
return(0, 0)
}
// Revert with `Error("TRANSFER_FAILED")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,9 +16,9 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "./MixinAuthorizable.sol";
import "../archive/MixinAuthorizable.sol";
contract ERC721Proxy is
@@ -28,7 +28,7 @@ contract ERC721Proxy is
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC721Token(address,uint256)"));
// solhint-disable-next-line payable-fallback
function ()
function ()
external
{
assembly {
@@ -93,10 +93,10 @@ contract ERC721Proxy is
// | Params | | 2 * 32 | function parameters: |
// | | 4 | 12 + 20 | 1. token address |
// | | 36 | | 2. tokenId |
// We construct calldata for the `token.transferFrom` ABI.
// The layout of this calldata is in the table below.
//
//
// | Area | Offset | Length | Contents |
// |----------|--------|---------|-------------------------------------|
// | Header | 0 | 4 | function selector |
@@ -121,7 +121,7 @@ contract ERC721Proxy is
// Any trailing data in transferFromSelector will be
// overwritten in the next `mstore` call.
mstore(0, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
/////// Setup Params Area ///////
// We copy the fields `from` and `to` in bulk
// from our own calldata to the new calldata.
@@ -145,7 +145,7 @@ contract ERC721Proxy is
if success {
return(0, 0)
}
// Revert with `Error("TRANSFER_FAILED")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,10 +16,10 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "./MixinAssetProxyDispatcher.sol";
import "./MixinAuthorizable.sol";
import "../archive/MixinAssetProxyDispatcher.sol";
import "../archive/MixinAuthorizable.sol";
contract MultiAssetProxy is
@@ -105,7 +105,7 @@ contract MultiAssetProxy is
// | | 36 | | 2. offset to nestedAssetData (*) |
// | Data | | | amounts: |
// | | 68 | 32 | amounts Length |
// | | 100 | a | amounts Contents |
// | | 100 | a | amounts Contents |
// | | | | nestedAssetData: |
// | | 100 + a | 32 | nestedAssetData Length |
// | | 132 + a | b | nestedAssetData Contents (offsets) |
@@ -149,8 +149,8 @@ contract MultiAssetProxy is
// + 32 (amounts offset)
let nestedAssetDataOffset := calldataload(add(assetDataOffset, 68))
// In order to find the start of the `amounts` contents, we must add:
// assetDataOffset
// In order to find the start of the `amounts` contents, we must add:
// assetDataOffset
// + 32 (assetData len)
// + 4 (assetProxyId)
// + amountsOffset
@@ -160,8 +160,8 @@ contract MultiAssetProxy is
// Load number of elements in `amounts`
let amountsLen := calldataload(sub(amountsContentsStart, 32))
// In order to find the start of the `nestedAssetData` contents, we must add:
// assetDataOffset
// In order to find the start of the `nestedAssetData` contents, we must add:
// assetDataOffset
// + 32 (assetData len)
// + 4 (assetProxyId)
// + nestedAssetDataOffset
@@ -190,10 +190,10 @@ contract MultiAssetProxy is
// Overwrite existing offset to `assetData` with our own
mstore(4, 128)
// Load `amount`
let amount := calldataload(100)
// Calculate number of bytes in `amounts` contents
let amountsByteLen := mul(amountsLen, 32)
@@ -208,7 +208,7 @@ contract MultiAssetProxy is
let amountsElement := calldataload(add(amountsContentsStart, i))
let totalAmount := mul(amountsElement, amount)
// Revert if `amount` != 0 and multiplication resulted in an overflow
// Revert if `amount` != 0 and multiplication resulted in an overflow
if iszero(or(
iszero(amount),
eq(div(totalAmount, amount), amountsElement)
@@ -228,7 +228,7 @@ contract MultiAssetProxy is
let nestedAssetDataElementOffset := calldataload(add(nestedAssetDataContentsStart, i))
// In order to find the start of the `nestedAssetData[i]` contents, we must add:
// assetDataOffset
// assetDataOffset
// + 32 (assetData len)
// + 4 (assetProxyId)
// + nestedAssetDataOffset
@@ -274,7 +274,7 @@ contract MultiAssetProxy is
mstore(164, assetProxies_slot)
assetProxy := sload(keccak256(132, 64))
}
// Revert if AssetProxy with given id does not exist
if iszero(assetProxy) {
// Revert with `Error("ASSET_PROXY_DOES_NOT_EXIST")`
@@ -284,7 +284,7 @@ contract MultiAssetProxy is
mstore(96, 0)
revert(0, 100)
}
// Copy `nestedAssetData[i]` from calldata to memory
calldatacopy(
132, // memory slot after `amounts[i]`
@@ -298,7 +298,7 @@ contract MultiAssetProxy is
assetProxy, // call address of asset proxy
0, // don't send any ETH
0, // pointer to start of input
add(164, nestedAssetDataElementLen), // length of input
add(164, nestedAssetDataElementLen), // length of input
0, // write output over memory that won't be reused
0 // don't copy output to memory
)

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.

View File

@@ -0,0 +1,98 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
import "../interfaces/IERC20Bridge.sol";
import "../interfaces/IEth2Dai.sol";
// solhint-disable space-after-comma
contract Eth2DaiBridge is
IERC20Bridge,
IWallet
{
/* Mainnet addresses */
address constant public ETH2DAI_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
/// (DAI or WETH) to the Eth2Dai contract, then transfers the bought
/// tokens to `to`.
/// @param toTokenAddress The token to give to `to` (either DAI or WETH).
/// @param to The recipient of the bought tokens.
/// @param amount Minimum amount of `toTokenAddress` tokens to buy.
/// @param bridgeData The abi-encoeded "from" token address.
/// @return success The magic bytes if successful.
function bridgeTransferFrom(
address toTokenAddress,
address /* from */,
address to,
uint256 amount,
bytes calldata bridgeData
)
external
returns (bytes4 success)
{
// Decode the bridge data to get the `fromTokenAddress`.
(address fromTokenAddress) = abi.decode(bridgeData, (address));
IEth2Dai exchange = _getEth2DaiContract();
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1));
// Try to sell all of this contract's `fromTokenAddress` token balance.
uint256 boughtAmount = _getEth2DaiContract().sellAllAmount(
address(fromTokenAddress),
IERC20Token(fromTokenAddress).balanceOf(address(this)),
toTokenAddress,
amount
);
// Transfer the converted `toToken`s to `to`.
LibERC20Token.transfer(toTokenAddress, to, boughtAmount);
return BRIDGE_SUCCESS;
}
/// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker
/// and sign for itself in orders. Always succeeds.
/// @return magicValue Magic success bytes, always.
function isValidSignature(
bytes32,
bytes calldata
)
external
view
returns (bytes4 magicValue)
{
return LEGACY_WALLET_MAGIC_VALUE;
}
/// @dev Overridable way to get the eth2dai contract.
/// @return exchange The Eth2Dai exchange contract.
function _getEth2DaiContract()
internal
view
returns (IEth2Dai exchange)
{
return IEth2Dai(ETH2DAI_ADDRESS);
}
}

View File

@@ -0,0 +1,219 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
import "../interfaces/IUniswapExchangeFactory.sol";
import "../interfaces/IUniswapExchange.sol";
import "../interfaces/IERC20Bridge.sol";
// solhint-disable space-after-comma
// solhint-disable not-rely-on-time
contract UniswapBridge is
IERC20Bridge,
IWallet
{
/* Mainnet addresses */
address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
address constant private WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// Struct to hold `bridgeTransferFrom()` local variables in memory and to avoid
// stack overflows.
struct WithdrawToState {
IUniswapExchange exchange;
uint256 fromTokenBalance;
IEtherToken weth;
}
// solhint-disable no-empty-blocks
/// @dev Payable fallback to receive ETH from uniswap.
function ()
external
payable
{}
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
/// `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress`
/// token encoded in the bridge data.
/// @param toTokenAddress The token to buy and transfer to `to`.
/// @param to The recipient of the bought tokens.
/// @param amount Minimum amount of `toTokenAddress` tokens to buy.
/// @param bridgeData The abi-encoded "from" token address.
/// @return success The magic bytes if successful.
function bridgeTransferFrom(
address toTokenAddress,
address /* from */,
address to,
uint256 amount,
bytes calldata bridgeData
)
external
returns (bytes4 success)
{
// State memory object to avoid stack overflows.
WithdrawToState memory state;
// Decode the bridge data to get the `fromTokenAddress`.
(address fromTokenAddress) = abi.decode(bridgeData, (address));
// Just transfer the tokens if they're the same.
if (fromTokenAddress == toTokenAddress) {
LibERC20Token.transfer(fromTokenAddress, to, amount);
return BRIDGE_SUCCESS;
}
// Get the exchange for the token pair.
state.exchange = _getUniswapExchangeForTokenPair(
fromTokenAddress,
toTokenAddress
);
// Get our balance of `fromTokenAddress` token.
state.fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this));
// Get the weth contract.
state.weth = getWethContract();
// Convert from WETH to a token.
if (fromTokenAddress == address(state.weth)) {
// Unwrap the WETH.
state.weth.withdraw(state.fromTokenBalance);
// Buy as much of `toTokenAddress` token with ETH as possible and
// transfer it to `to`.
state.exchange.ethToTokenTransferInput.value(state.fromTokenBalance)(
// Minimum buy amount.
amount,
// Expires after this block.
block.timestamp,
// Recipient is `to`.
to
);
// Convert from a token to WETH.
} else if (toTokenAddress == address(state.weth)) {
// Grant the exchange an allowance.
_grantExchangeAllowance(state.exchange, fromTokenAddress);
// Buy as much ETH with `fromTokenAddress` token as possible.
uint256 ethBought = state.exchange.tokenToEthSwapInput(
// Sell all tokens we hold.
state.fromTokenBalance,
// Minimum buy amount.
amount,
// Expires after this block.
block.timestamp
);
// Wrap the ETH.
state.weth.deposit.value(ethBought)();
// Transfer the WETH to `to`.
IEtherToken(toTokenAddress).transfer(to, ethBought);
// Convert from one token to another.
} else {
// Grant the exchange an allowance.
_grantExchangeAllowance(state.exchange, fromTokenAddress);
// Buy as much `toTokenAddress` token with `fromTokenAddress` token
// and transfer it to `to`.
state.exchange.tokenToTokenTransferInput(
// Sell all tokens we hold.
state.fromTokenBalance,
// Minimum buy amount.
amount,
// No minimum intermediate ETH buy amount.
0,
// Expires after this block.
block.timestamp,
// Recipient is `to`.
to,
// Convert to `toTokenAddress`.
toTokenAddress
);
}
return BRIDGE_SUCCESS;
}
/// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker
/// and sign for itself in orders. Always succeeds.
/// @return magicValue Success bytes, always.
function isValidSignature(
bytes32,
bytes calldata
)
external
view
returns (bytes4 magicValue)
{
return LEGACY_WALLET_MAGIC_VALUE;
}
/// @dev Overridable way to get the weth contract.
/// @return token The WETH contract.
function getWethContract()
public
view
returns (IEtherToken token)
{
return IEtherToken(WETH_ADDRESS);
}
/// @dev Overridable way to get the uniswap exchange factory contract.
/// @return factory The exchange factory contract.
function getUniswapExchangeFactoryContract()
public
view
returns (IUniswapExchangeFactory factory)
{
return IUniswapExchangeFactory(UNISWAP_EXCHANGE_FACTORY_ADDRESS);
}
/// @dev Grants an unlimited allowance to the exchange for its token
/// on behalf of this contract.
/// @param exchange The Uniswap token exchange.
/// @param tokenAddress The token address for the exchange.
function _grantExchangeAllowance(IUniswapExchange exchange, address tokenAddress)
private
{
LibERC20Token.approve(tokenAddress, address(exchange), uint256(-1));
}
/// @dev Retrieves the uniswap exchange for a given token pair.
/// In the case of a WETH-token exchange, this will be the non-WETH token.
/// In th ecase of a token-token exchange, this will be the first token.
/// @param fromTokenAddress The address of the token we are converting from.
/// @param toTokenAddress The address of the token we are converting to.
/// @return exchange The uniswap exchange.
function _getUniswapExchangeForTokenPair(
address fromTokenAddress,
address toTokenAddress
)
private
view
returns (IUniswapExchange exchange)
{
address exchangeTokenAddress = fromTokenAddress;
// Whichever isn't WETH is the exchange token.
if (fromTokenAddress == address(getWethContract())) {
exchangeTokenAddress = toTokenAddress;
}
exchange = getUniswapExchangeFactoryContract().getExchange(exchangeTokenAddress);
require(address(exchange) != address(0), "NO_UNISWAP_EXCHANGE_FOR_TOKEN");
return exchange;
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -17,7 +17,7 @@
*/
// solhint-disable
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
@@ -26,33 +26,63 @@ pragma experimental ABIEncoderV2;
// This argument is ABI encoded as one of the methods of this interface.
interface IAssetData {
/// @dev Function signature for encoding ERC20 assetData.
/// @param tokenAddress Address of ERC20Token contract.
function ERC20Token(address tokenAddress)
external;
/// @dev Function signature for encoding ERC721 assetData.
/// @param tokenAddress Address of ERC721 token contract.
/// @param tokenId Id of ERC721 token to be transferred.
function ERC721Token(
address tokenAddress,
uint256 tokenId
)
external;
/// @dev Function signature for encoding ERC1155 assetData.
/// @param tokenAddress Address of ERC1155 token contract.
/// @param tokenIds Array of ids of tokens to be transferred.
/// @param values Array of values that correspond to each token id to be transferred.
/// Note that each value will be multiplied by the amount being filled in the order before transferring.
/// @param callbackData Extra data to be passed to receiver's `onERC1155Received` callback function.
function ERC1155Assets(
address tokenAddress,
uint256[] calldata tokenIds,
uint256[] calldata tokenValues,
uint256[] calldata values,
bytes calldata callbackData
)
external;
/// @dev Function signature for encoding MultiAsset assetData.
/// @param values Array of amounts that correspond to each asset to be transferred.
/// Note that each value will be multiplied by the amount being filled in the order before transferring.
/// @param nestedAssetData Array of assetData fields that will be be dispatched to their correspnding AssetProxy contract.
function MultiAsset(
uint256[] calldata amounts,
uint256[] calldata values,
bytes[] calldata nestedAssetData
)
external;
/// @dev Function signature for encoding StaticCall assetData.
/// @param staticCallTargetAddress Address that will execute the staticcall.
/// @param staticCallData Data that will be executed via staticcall on the staticCallTargetAddress.
/// @param expectedReturnDataHash Keccak-256 hash of the expected staticcall return data.
function StaticCall(
address callTarget,
address staticCallTargetAddress,
bytes calldata staticCallData,
bytes32 callResultHash
bytes32 expectedReturnDataHash
)
external;
/// @dev Function signature for encoding ERC20Bridge assetData.
/// @param tokenAddress Address of token to transfer.
/// @param bridgeAddress Address of the bridge contract.
/// @param bridgeData Arbitrary data to be passed to the bridge contract.
function ERC20Bridge(
address tokenAddress,
address bridgeAddress,
bytes calldata bridgeData
)
external;
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,9 +16,7 @@
*/
pragma solidity ^0.5.5;
import "./IAuthorizable.sol";
pragma solidity ^0.5.9;
contract IAssetProxy {

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,11 +16,17 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
contract IAssetProxyDispatcher {
// Logs registration of new asset proxy
event AssetProxyRegistered(
bytes4 id, // Id of new registered AssetProxy.
address assetProxy // Address of new registered AssetProxy.
);
/// @dev Registers an asset proxy to its asset proxy id.
/// Once an asset proxy is registered, it cannot be unregistered.
/// @param assetProxy Address of new asset proxy to register.

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,7 +16,7 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/interfaces/IOwnable.sol";
@@ -24,6 +24,18 @@ import "@0x/contracts-utils/contracts/src/interfaces/IOwnable.sol";
contract IAuthorizable is
IOwnable
{
// Event logged when a new address is authorized.
event AuthorizedAddressAdded(
address indexed target,
address indexed caller
);
// Event logged when a currently authorized address is unauthorized.
event AuthorizedAddressRemoved(
address indexed target,
address indexed caller
);
/// @dev Authorizes an address.
/// @param target Address to authorize.
function addAuthorizedAddress(address target)
@@ -42,7 +54,7 @@ contract IAuthorizable is
uint256 index
)
external;
/// @dev Gets all authorized addresses.
/// @return Array of authorized addresses.
function getAuthorizedAddresses()

View File

@@ -0,0 +1,43 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
contract IERC20Bridge {
// @dev Result of a successful bridge call.
bytes4 constant internal BRIDGE_SUCCESS = 0xdc1600f3;
/// @dev Transfers `amount` of the ERC20 `tokenAddress` from `from` to `to`.
/// @param tokenAddress The address of the ERC20 token to transfer.
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
/// @param bridgeData Arbitrary asset data needed by the bridge contract.
/// @return success The magic bytes `0x37708e9b` if successful.
function bridgeTransferFrom(
address tokenAddress,
address from,
address to,
uint256 amount,
bytes calldata bridgeData
)
external
returns (bytes4 success);
}

View File

@@ -0,0 +1,38 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
interface IEth2Dai {
/// @dev Sell `sellAmount` of `fromToken` token and receive `toToken` token.
/// @param fromToken The token being sold.
/// @param sellAmount The amount of `fromToken` token being sold.
/// @param toToken The token being bought.
/// @param minFillAmount Minimum amount of `toToken` token to buy.
/// @return fillAmount Amount of `toToken` bought.
function sellAllAmount(
address fromToken,
uint256 sellAmount,
address toToken,
uint256 minFillAmount
)
external
returns (uint256 fillAmount);
}

View File

@@ -0,0 +1,77 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
interface IUniswapExchange {
/// @dev Buys at least `minTokensBought` tokens with ETH and transfer them
/// to `recipient`.
/// @param minTokensBought The minimum number of tokens to buy.
/// @param deadline Time when this order expires.
/// @param recipient Who to transfer the tokens to.
/// @return tokensBought Amount of tokens bought.
function ethToTokenTransferInput(
uint256 minTokensBought,
uint256 deadline,
address recipient
)
external
payable
returns (uint256 tokensBought);
/// @dev Buys at least `minEthBought` ETH with tokens.
/// @param tokensSold Amount of tokens to sell.
/// @param minEthBought The minimum amount of ETH to buy.
/// @param deadline Time when this order expires.
/// @return ethBought Amount of tokens bought.
function tokenToEthSwapInput(
uint256 tokensSold,
uint256 minEthBought,
uint256 deadline
)
external
returns (uint256 ethBought);
/// @dev Buys at least `minTokensBought` tokens with the exchange token
/// and transfer them to `recipient`.
/// @param minTokensBought The minimum number of tokens to buy.
/// @param minEthBought The minimum amount of intermediate ETH to buy.
/// @param deadline Time when this order expires.
/// @param recipient Who to transfer the tokens to.
/// @param toTokenAddress The token being bought.
/// @return tokensBought Amount of tokens bought.
function tokenToTokenTransferInput(
uint256 tokensSold,
uint256 minTokensBought,
uint256 minEthBought,
uint256 deadline,
address recipient,
address toTokenAddress
)
external
returns (uint256 tokensBought);
/// @dev Retrieves the token that is associated with this exchange.
/// @return tokenAddress The token address.
function toTokenAddress()
external
view
returns (address tokenAddress);
}

View File

@@ -0,0 +1,32 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
import "./IUniswapExchange.sol";
interface IUniswapExchangeFactory {
/// @dev Get the exchange for a token.
/// @param tokenAddress The address of the token contract.
function getExchange(address tokenAddress)
external
view
returns (IUniswapExchange);
}

View File

@@ -1,40 +0,0 @@
/*
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

@@ -1,45 +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;
import "../interfaces/IAssetProxyDispatcher.sol";
contract MAssetProxyDispatcher is
IAssetProxyDispatcher
{
// Logs registration of new asset proxy
event AssetProxyRegistered(
bytes4 id, // Id of new registered AssetProxy.
address assetProxy // Address of new registered AssetProxy.
);
/// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.
/// @param assetData Byte array encoded for the asset.
/// @param from Address to transfer token from.
/// @param to Address to transfer token to.
/// @param amount Amount of token to transfer.
function dispatchTransferFrom(
bytes memory assetData,
address from,
address to,
uint256 amount
)
internal;
}

View File

@@ -1,41 +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;
import "../interfaces/IAuthorizable.sol";
contract MAuthorizable is
IAuthorizable
{
// Event logged when a new address is authorized.
event AuthorizedAddressAdded(
address indexed target,
address indexed caller
);
// Event logged when a currently authorized address is unauthorized.
event AuthorizedAddressRemoved(
address indexed target,
address indexed caller
);
/// @dev Only authorized addresses can invoke functions with this modifier.
modifier onlyAuthorized { revert(); _; }
}

View File

@@ -0,0 +1,108 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "../src/interfaces/IERC20Bridge.sol";
/// @dev Test bridge token
contract TestERC20BridgeToken {
mapping (address => uint256) private _balances;
function addBalance(address owner, int256 amount)
external
{
setBalance(owner, uint256(int256(balanceOf(owner)) + amount));
}
function setBalance(address owner, uint256 balance)
public
{
_balances[owner] = balance;
}
function balanceOf(address owner)
public
view
returns (uint256)
{
return _balances[owner];
}
}
/// @dev Test bridge contract.
contract TestERC20Bridge is
IERC20Bridge
{
TestERC20BridgeToken public testToken;
event BridgeWithdrawTo(
address tokenAddress,
address from,
address to,
uint256 amount,
bytes bridgeData
);
constructor() public {
testToken = new TestERC20BridgeToken();
}
function setTestTokenBalance(address owner, uint256 balance)
external
{
testToken.setBalance(owner, balance);
}
function bridgeTransferFrom(
address tokenAddress,
address from,
address to,
uint256 amount,
bytes calldata bridgeData
)
external
returns (bytes4)
{
emit BridgeWithdrawTo(
tokenAddress,
from,
to,
amount,
bridgeData
);
// Unpack the bridgeData.
(
int256 transferAmount,
bytes memory revertData,
bytes memory returnData
) = abi.decode(bridgeData, (int256, bytes, bytes));
// If `revertData` is set, revert.
if (revertData.length != 0) {
assembly { revert(add(revertData, 0x20), mload(revertData)) }
}
// Increase `to`'s balance by `transferAmount`.
TestERC20BridgeToken(tokenAddress).addBalance(to, transferAmount);
// Return `returnData`.
assembly { return(add(returnData, 0x20), mload(returnData)) }
}
}

View File

@@ -0,0 +1,202 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "../src/bridges/Eth2DaiBridge.sol";
import "../src/interfaces/IEth2Dai.sol";
// solhint-disable no-simple-event-func-name
contract TestEvents {
event TokenTransfer(
address token,
address from,
address to,
uint256 amount
);
event TokenApprove(
address token,
address spender,
uint256 allowance
);
function raiseTokenTransfer(
address from,
address to,
uint256 amount
)
external
{
emit TokenTransfer(
msg.sender,
from,
to,
amount
);
}
function raiseTokenApprove(address spender, uint256 allowance)
external
{
emit TokenApprove(msg.sender, spender, allowance);
}
}
/// @dev A minimalist ERC20 token.
contract TestToken {
mapping (address => uint256) public balances;
string private _nextTransferRevertReason;
bytes private _nextTransferReturnData;
/// @dev Just calls `raiseTokenTransfer()` on the caller.
function transfer(address to, uint256 amount)
external
returns (bool)
{
TestEvents(msg.sender).raiseTokenTransfer(msg.sender, to, amount);
if (bytes(_nextTransferRevertReason).length != 0) {
revert(_nextTransferRevertReason);
}
bytes memory returnData = _nextTransferReturnData;
assembly { return(add(returnData, 0x20), mload(returnData)) }
}
/// @dev Set the balance for `owner`.
function setBalance(address owner, uint256 balance)
external
{
balances[owner] = balance;
}
/// @dev Set the behavior of the `transfer()` call.
function setTransferBehavior(
string calldata revertReason,
bytes calldata returnData
)
external
{
_nextTransferRevertReason = revertReason;
_nextTransferReturnData = returnData;
}
/// @dev Just calls `raiseTokenApprove()` on the caller.
function approve(address spender, uint256 allowance)
external
returns (bool)
{
TestEvents(msg.sender).raiseTokenApprove(spender, allowance);
return true;
}
/// @dev Retrieve the balance for `owner`.
function balanceOf(address owner)
external
view
returns (uint256)
{
return balances[owner];
}
}
/// @dev Eth2DaiBridge overridden to mock tokens and
/// implement IEth2Dai.
contract TestEth2DaiBridge is
TestEvents,
IEth2Dai,
Eth2DaiBridge
{
event SellAllAmount(
address sellToken,
uint256 sellTokenAmount,
address buyToken,
uint256 minimumFillAmount
);
mapping (address => TestToken) public testTokens;
string private _nextRevertReason;
uint256 private _nextFillAmount;
/// @dev Create a token and set this contract's balance.
function createToken(uint256 balance)
external
returns (address tokenAddress)
{
TestToken token = new TestToken();
testTokens[address(token)] = token;
token.setBalance(address(this), balance);
return address(token);
}
/// @dev Set the behavior for `IEth2Dai.sellAllAmount()`.
function setFillBehavior(string calldata revertReason, uint256 fillAmount)
external
{
_nextRevertReason = revertReason;
_nextFillAmount = fillAmount;
}
/// @dev Set the behavior of a token's `transfer()`.
function setTransferBehavior(
address tokenAddress,
string calldata revertReason,
bytes calldata returnData
)
external
{
testTokens[tokenAddress].setTransferBehavior(revertReason, returnData);
}
/// @dev Implementation of `IEth2Dai.sellAllAmount()`
function sellAllAmount(
address sellTokenAddress,
uint256 sellTokenAmount,
address buyTokenAddress,
uint256 minimumFillAmount
)
external
returns (uint256 fillAmount)
{
emit SellAllAmount(
sellTokenAddress,
sellTokenAmount,
buyTokenAddress,
minimumFillAmount
);
if (bytes(_nextRevertReason).length != 0) {
revert(_nextRevertReason);
}
return _nextFillAmount;
}
// @dev This contract will double as the Eth2Dai contract.
function _getEth2DaiContract()
internal
view
returns (IEth2Dai)
{
return IEth2Dai(address(this));
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.

View File

@@ -0,0 +1,432 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "../src/bridges/UniswapBridge.sol";
import "../src/interfaces/IUniswapExchangeFactory.sol";
import "../src/interfaces/IUniswapExchange.sol";
// solhint-disable no-simple-event-func-name
contract TestEventsRaiser {
event TokenTransfer(
address token,
address from,
address to,
uint256 amount
);
event TokenApprove(
address spender,
uint256 allowance
);
event WethDeposit(
uint256 amount
);
event WethWithdraw(
uint256 amount
);
event EthToTokenTransferInput(
address exchange,
uint256 minTokensBought,
uint256 deadline,
address recipient
);
event TokenToEthSwapInput(
address exchange,
uint256 tokensSold,
uint256 minEthBought,
uint256 deadline
);
event TokenToTokenTransferInput(
address exchange,
uint256 tokensSold,
uint256 minTokensBought,
uint256 minEthBought,
uint256 deadline,
address recipient,
address toTokenAddress
);
function raiseEthToTokenTransferInput(
uint256 minTokensBought,
uint256 deadline,
address recipient
)
external
{
emit EthToTokenTransferInput(
msg.sender,
minTokensBought,
deadline,
recipient
);
}
function raiseTokenToEthSwapInput(
uint256 tokensSold,
uint256 minEthBought,
uint256 deadline
)
external
{
emit TokenToEthSwapInput(
msg.sender,
tokensSold,
minEthBought,
deadline
);
}
function raiseTokenToTokenTransferInput(
uint256 tokensSold,
uint256 minTokensBought,
uint256 minEthBought,
uint256 deadline,
address recipient,
address toTokenAddress
)
external
{
emit TokenToTokenTransferInput(
msg.sender,
tokensSold,
minTokensBought,
minEthBought,
deadline,
recipient,
toTokenAddress
);
}
function raiseTokenTransfer(
address from,
address to,
uint256 amount
)
external
{
emit TokenTransfer(
msg.sender,
from,
to,
amount
);
}
function raiseTokenApprove(address spender, uint256 allowance)
external
{
emit TokenApprove(spender, allowance);
}
function raiseWethDeposit(uint256 amount)
external
{
emit WethDeposit(amount);
}
function raiseWethWithdraw(uint256 amount)
external
{
emit WethWithdraw(amount);
}
}
/// @dev A minimalist ERC20/WETH token.
contract TestToken {
using LibSafeMath for uint256;
mapping (address => uint256) public balances;
string private _nextRevertReason;
/// @dev Set the balance for `owner`.
function setBalance(address owner)
external
payable
{
balances[owner] = msg.value;
}
/// @dev Set the revert reason for `transfer()`,
/// `deposit()`, and `withdraw()`.
function setRevertReason(string calldata reason)
external
{
_nextRevertReason = reason;
}
/// @dev Just calls `raiseTokenTransfer()` on the caller.
function transfer(address to, uint256 amount)
external
returns (bool)
{
_revertIfReasonExists();
TestEventsRaiser(msg.sender).raiseTokenTransfer(msg.sender, to, amount);
return true;
}
/// @dev Just calls `raiseTokenApprove()` on the caller.
function approve(address spender, uint256 allowance)
external
returns (bool)
{
TestEventsRaiser(msg.sender).raiseTokenApprove(spender, allowance);
return true;
}
/// @dev `IWETH.deposit()` that increases balances and calls
/// `raiseWethDeposit()` on the caller.
function deposit()
external
payable
{
_revertIfReasonExists();
balances[msg.sender] += balances[msg.sender].safeAdd(msg.value);
TestEventsRaiser(msg.sender).raiseWethDeposit(msg.value);
}
/// @dev `IWETH.withdraw()` that just reduces balances and calls
/// `raiseWethWithdraw()` on the caller.
function withdraw(uint256 amount)
external
{
_revertIfReasonExists();
balances[msg.sender] = balances[msg.sender].safeSub(amount);
msg.sender.transfer(amount);
TestEventsRaiser(msg.sender).raiseWethWithdraw(amount);
}
/// @dev Retrieve the balance for `owner`.
function balanceOf(address owner)
external
view
returns (uint256)
{
return balances[owner];
}
function _revertIfReasonExists()
private
view
{
if (bytes(_nextRevertReason).length != 0) {
revert(_nextRevertReason);
}
}
}
contract TestExchange is
IUniswapExchange
{
address public tokenAddress;
string private _nextRevertReason;
constructor(address _tokenAddress) public {
tokenAddress = _tokenAddress;
}
function setFillBehavior(
string calldata revertReason
)
external
payable
{
_nextRevertReason = revertReason;
}
function ethToTokenTransferInput(
uint256 minTokensBought,
uint256 deadline,
address recipient
)
external
payable
returns (uint256 tokensBought)
{
TestEventsRaiser(msg.sender).raiseEthToTokenTransferInput(
minTokensBought,
deadline,
recipient
);
_revertIfReasonExists();
return address(this).balance;
}
function tokenToEthSwapInput(
uint256 tokensSold,
uint256 minEthBought,
uint256 deadline
)
external
returns (uint256 ethBought)
{
TestEventsRaiser(msg.sender).raiseTokenToEthSwapInput(
tokensSold,
minEthBought,
deadline
);
_revertIfReasonExists();
uint256 fillAmount = address(this).balance;
msg.sender.transfer(fillAmount);
return fillAmount;
}
function tokenToTokenTransferInput(
uint256 tokensSold,
uint256 minTokensBought,
uint256 minEthBought,
uint256 deadline,
address recipient,
address toTokenAddress
)
external
returns (uint256 tokensBought)
{
TestEventsRaiser(msg.sender).raiseTokenToTokenTransferInput(
tokensSold,
minTokensBought,
minEthBought,
deadline,
recipient,
toTokenAddress
);
_revertIfReasonExists();
return address(this).balance;
}
function toTokenAddress()
external
view
returns (address _tokenAddress)
{
return tokenAddress;
}
function _revertIfReasonExists()
private
view
{
if (bytes(_nextRevertReason).length != 0) {
revert(_nextRevertReason);
}
}
}
/// @dev UniswapBridge overridden to mock tokens and implement IUniswapExchangeFactory.
contract TestUniswapBridge is
IUniswapExchangeFactory,
TestEventsRaiser,
UniswapBridge
{
TestToken public wethToken;
// Token address to TestToken instance.
mapping (address => TestToken) private _testTokens;
// Token address to TestExchange instance.
mapping (address => TestExchange) private _testExchanges;
constructor() public {
wethToken = new TestToken();
_testTokens[address(wethToken)] = wethToken;
}
/// @dev Sets the balance of this contract for an existing token.
/// The wei attached will be the balance.
function setTokenBalance(address tokenAddress)
external
payable
{
TestToken token = _testTokens[tokenAddress];
token.deposit.value(msg.value)();
}
/// @dev Sets the revert reason for an existing token.
function setTokenRevertReason(address tokenAddress, string calldata revertReason)
external
{
TestToken token = _testTokens[tokenAddress];
token.setRevertReason(revertReason);
}
/// @dev Create a token and exchange (if they don't exist) for a new token
/// and sets the exchange revert and fill behavior. The wei attached
/// will be the fill amount for the exchange.
/// @param tokenAddress The token address. If zero, one will be created.
/// @param revertReason The revert reason for exchange operations.
function createTokenAndExchange(
address tokenAddress,
string calldata revertReason
)
external
payable
returns (TestToken token, TestExchange exchange)
{
token = TestToken(tokenAddress);
if (tokenAddress == address(0)) {
token = new TestToken();
}
_testTokens[address(token)] = token;
exchange = _testExchanges[address(token)];
if (address(exchange) == address(0)) {
_testExchanges[address(token)] = exchange = new TestExchange(address(token));
}
exchange.setFillBehavior.value(msg.value)(revertReason);
return (token, exchange);
}
/// @dev `IUniswapExchangeFactory.getExchange`
function getExchange(address tokenAddress)
external
view
returns (IUniswapExchange)
{
return IUniswapExchange(_testExchanges[tokenAddress]);
}
// @dev Use `wethToken`.
function getWethContract()
public
view
returns (IEtherToken)
{
return IEtherToken(address(wethToken));
}
// @dev This contract will double as the Uniswap contract.
function getUniswapExchangeFactoryContract()
public
view
returns (IUniswapExchangeFactory)
{
return IUniswapExchangeFactory(address(this));
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-asset-proxy",
"version": "2.2.5",
"version": "2.3.0-beta.1",
"engines": {
"node": ">=6.12"
},
@@ -12,7 +12,7 @@
"scripts": {
"build": "yarn pre_build && tsc -b",
"build:ci": "yarn build",
"pre_build": "run-s compile generate_contract_wrappers",
"pre_build": "run-s compile contracts:gen 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",
@@ -22,7 +22,7 @@
"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",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
@@ -31,10 +31,11 @@
"coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test",
"contracts:gen": "contracts-gen",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
"compile:truffle": "truffle compile"
},
"config": {
"abis": "./generated-artifacts/@(ERC1155Proxy|ERC20Proxy|ERC721Proxy|IAssetData|IAssetProxy|IAuthorizable|MixinAuthorizable|MultiAssetProxy|StaticCallProxy|TestStaticCallTarget).json",
"abis": "./generated-artifacts/@(ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IERC20Bridge|IEth2Dai|IUniswapExchange|IUniswapExchangeFactory|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestERC20Bridge|TestEth2DaiBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
@@ -47,12 +48,12 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
"devDependencies": {
"@0x/abi-gen": "^4.1.0",
"@0x/contracts-gen": "^1.0.13",
"@0x/contracts-test-utils": "^3.1.13",
"@0x/dev-utils": "^2.3.0",
"@0x/sol-compiler": "^3.1.12",
"@0x/tslint-config": "^3.0.1",
"@0x/abi-gen": "^4.4.0-beta.1",
"@0x/contracts-gen": "^1.1.0-beta.1",
"@0x/contracts-test-utils": "^3.2.0-beta.1",
"@0x/dev-utils": "^2.4.0-beta.1",
"@0x/sol-compiler": "^3.2.0-beta.1",
"@0x/tslint-config": "^3.1.0-beta.1",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "*",
@@ -65,21 +66,23 @@
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.3.1",
"@0x/contracts-erc1155": "^1.1.12",
"@0x/contracts-erc20": "^2.2.11",
"@0x/contracts-erc721": "^2.1.12",
"@0x/contracts-utils": "^3.2.1",
"@0x/order-utils": "^8.2.5",
"@0x/types": "^2.4.1",
"@0x/typescript-typings": "^4.2.4",
"@0x/utils": "^4.5.0",
"@0x/web3-wrapper": "^6.0.10",
"ethereum-types": "^2.1.4",
"@0x/base-contract": "^5.5.0-beta.1",
"@0x/contracts-dev-utils": "^0.1.0-beta.1",
"@0x/contracts-erc1155": "^1.2.0-beta.1",
"@0x/contracts-erc20": "^2.3.0-beta.1",
"@0x/contracts-erc721": "^2.2.0-beta.1",
"@0x/contracts-utils": "^3.3.0-beta.1",
"@0x/order-utils": "^8.5.0-beta.1",
"@0x/types": "^2.5.0-beta.1",
"@0x/typescript-typings": "^4.4.0-beta.1",
"@0x/utils": "^4.6.0-beta.1",
"@0x/web3-wrapper": "^6.1.0-beta.1",
"ethereum-types": "^2.2.0-beta.1",
"ethereumjs-util": "^5.1.1",
"lodash": "^4.17.11"
},

View File

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

View File

@@ -4,12 +4,25 @@
* -----------------------------------------------------------------------------
*/
export * from '../generated-wrappers/erc1155_proxy';
export * from '../generated-wrappers/erc20_bridge_proxy';
export * from '../generated-wrappers/erc20_proxy';
export * from '../generated-wrappers/erc721_proxy';
export * from '../generated-wrappers/eth2_dai_bridge';
export * from '../generated-wrappers/i_asset_data';
export * from '../generated-wrappers/i_asset_proxy';
export * from '../generated-wrappers/i_asset_proxy_dispatcher';
export * from '../generated-wrappers/i_authorizable';
export * from '../generated-wrappers/i_erc20_bridge';
export * from '../generated-wrappers/i_eth2_dai';
export * from '../generated-wrappers/i_uniswap_exchange';
export * from '../generated-wrappers/i_uniswap_exchange_factory';
export * from '../generated-wrappers/mixin_asset_proxy_dispatcher';
export * from '../generated-wrappers/mixin_authorizable';
export * from '../generated-wrappers/multi_asset_proxy';
export * from '../generated-wrappers/ownable';
export * from '../generated-wrappers/static_call_proxy';
export * from '../generated-wrappers/test_erc20_bridge';
export * from '../generated-wrappers/test_eth2_dai_bridge';
export * from '../generated-wrappers/test_static_call_target';
export * from '../generated-wrappers/test_uniswap_bridge';
export * from '../generated-wrappers/uniswap_bridge';

View File

@@ -1,11 +1,4 @@
import {
chaiSetup,
constants,
expectTransactionFailedAsync,
provider,
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { chaiSetup, expectTransactionFailedAsync, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';
@@ -27,9 +20,11 @@ describe('Authorizable', () => {
before(async () => {
await blockchainLifecycle.startAsync();
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync();
[owner, address, notOwner] = _.slice(accounts, 0, 3);
@@ -40,34 +35,31 @@ describe('Authorizable', () => {
artifacts,
);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
describe('addAuthorizedAddress', () => {
it('should throw if not called by owner', async () => {
return expectTransactionFailedAsync(
it('should revert if not called by owner', async () => {
await expectTransactionFailedAsync(
authorizable.addAuthorizedAddress.sendTransactionAsync(notOwner, { from: notOwner }),
RevertReason.OnlyContractOwner,
);
});
it('should allow owner to add an authorized address', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
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 authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
it('should revert if owner attempts to authorize a duplicate address', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
return expectTransactionFailedAsync(
authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
RevertReason.TargetAlreadyAuthorized,
@@ -76,36 +68,22 @@ describe('Authorizable', () => {
});
describe('removeAuthorizedAddress', () => {
it('should throw if not called by owner', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
from: notOwner,
}),
it('should revert if not called by owner', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
await expectTransactionFailedAsync(
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { from: notOwner }),
RevertReason.OnlyContractOwner,
);
});
it('should allow owner to remove an authorized address', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const isAuthorized = await authorizable.authorized.callAsync(address);
expect(isAuthorized).to.be.false();
});
it('should throw if owner attempts to remove an address that is not authorized', async () => {
it('should revert if owner attempts to remove an address that is not authorized', async () => {
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
from: owner,
@@ -116,26 +94,19 @@ describe('Authorizable', () => {
});
describe('removeAuthorizedAddressAtIndex', () => {
it('should throw if not called by owner', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
it('should revert if not called by owner', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const index = new BigNumber(0);
return expectTransactionFailedAsync(
await expectTransactionFailedAsync(
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
from: notOwner,
}),
RevertReason.OnlyContractOwner,
);
});
it('should throw if index is >= authorities.length', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
it('should revert if index is >= authorities.length', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const index = new BigNumber(1);
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
@@ -144,7 +115,8 @@ describe('Authorizable', () => {
RevertReason.IndexOutOfBounds,
);
});
it('should throw if owner attempts to remove an address that is not authorized', async () => {
it('should revert if owner attempts to remove an address that is not authorized', async () => {
const index = new BigNumber(0);
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
@@ -153,19 +125,12 @@ describe('Authorizable', () => {
RevertReason.TargetNotAuthorized,
);
});
it('should throw if address at index does not match target', async () => {
it('should revert if address at index does not match target', async () => {
const address1 = address;
const address2 = notOwner;
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address1,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address2,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address1, { from: owner });
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address2, { from: owner });
const address1Index = new BigNumber(0);
return expectTransactionFailedAsync(
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address2, address1Index, {
@@ -174,19 +139,13 @@ describe('Authorizable', () => {
RevertReason.AuthorizedAddressMismatch,
);
});
it('should allow owner to remove an authorized address', async () => {
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const index = new BigNumber(0);
await authorizable.removeAuthorizedAddressAtIndex.awaitTransactionSuccessAsync(
address,
index,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.removeAuthorizedAddressAtIndex.awaitTransactionSuccessAsync(address, index, {
from: owner,
});
const isAuthorized = await authorizable.authorized.callAsync(address);
expect(isAuthorized).to.be.false();
});
@@ -196,19 +155,11 @@ describe('Authorizable', () => {
it('should return all authorized addresses', async () => {
const initial = await authorizable.getAuthorizedAddresses.callAsync();
expect(initial).to.have.length(0);
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const afterAdd = await authorizable.getAuthorizedAddresses.callAsync();
expect(afterAdd).to.have.length(1);
expect(afterAdd).to.include(address);
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(
address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(address, { from: owner });
const afterRemove = await authorizable.getAuthorizedAddresses.callAsync();
expect(afterRemove).to.have.length(0);
});

View File

@@ -1,3 +1,4 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import {
artifacts as erc1155Artifacts,
DummyERC1155ReceiverBatchTokenReceivedEventArgs,
@@ -15,15 +16,14 @@ import {
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 { BigNumber } from '@0x/utils';
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types';
import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';
import { artifacts, ERC1155ProxyContract, ERC1155ProxyWrapper } from '../src';
import { artifacts, ERC1155ProxyContract, ERC1155ProxyWrapper, IAssetDataContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
@@ -59,6 +59,8 @@ describe('ERC1155Proxy', () => {
// tokens
let fungibleTokens: BigNumber[];
let nonFungibleTokensOwnedBySpender: BigNumber[];
// devUtils for encoding and decoding assetData
let devUtils: DevUtilsContract;
// tests
before(async () => {
await blockchainLifecycle.startAsync();
@@ -72,16 +74,8 @@ describe('ERC1155Proxy', () => {
const usedAddresses = ([owner, notAuthorized, authorized, spender, receiver] = _.slice(accounts, 0, 5));
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
erc1155Proxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(authorized, { from: owner });
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(erc1155Proxy.address, { from: owner });
// deploy & configure ERC1155 tokens and receiver
[erc1155Wrapper] = await erc1155ProxyWrapper.deployDummyContractsAsync();
erc1155Contract = erc1155Wrapper.getContract();
@@ -103,6 +97,8 @@ describe('ERC1155Proxy', () => {
tokenBalances.nonFungible[spender][erc1155Contract.address][nonFungibleTokenAsString][0];
nonFungibleTokensOwnedBySpender.push(nonFungibleTokenHeldBySpender);
});
// set up devUtils
devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider, { from: owner });
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -638,7 +634,7 @@ describe('ERC1155Proxy', () => {
return value.times(valueMultiplier);
});
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -696,25 +692,18 @@ describe('ERC1155Proxy', () => {
const tokenUri = '';
for (const tokenToCreate of tokensToCreate) {
// create token
await erc1155Wrapper.getContract().createWithType.awaitTransactionSuccessAsync(
tokenToCreate,
tokenUri,
{
await erc1155Wrapper
.getContract()
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
});
// mint balance for spender
await erc1155Wrapper.getContract().mintFungible.awaitTransactionSuccessAsync(
tokenToCreate,
[spender],
[spenderInitialBalance],
{
await erc1155Wrapper
.getContract()
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
});
}
///// Step 2/5 /////
// Check balances before transfer
@@ -747,18 +736,16 @@ describe('ERC1155Proxy', () => {
const tokensToTransfer = [new BigNumber(1), new BigNumber(2)];
const valuesToTransfer = tokensToTransfer;
const valueMultiplier = new BigNumber(2);
const assetData = assetDataUtils.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
// remove the function selector and contract address from check, as these change on each test
const offsetToTokenIds = 74;
const assetDataWithoutContractAddress = assetData.substr(offsetToTokenIds);
const expectedAssetDataWithoutContractAddress =
// hand encode optimized assetData because our tooling (based on LibAssetData.sol/encodeERC1155AssetData) does not use optimized encoding
const assetDataContract = new IAssetDataContract(constants.NULL_ADDRESS, provider);
const selector = assetDataContract.ERC1155Assets.getSelector();
const assetDataWithoutContractAddress =
'0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040102030400000000000000000000000000000000000000000000000000000000';
expect(assetDataWithoutContractAddress).to.be.equal(expectedAssetDataWithoutContractAddress);
const assetData = `${selector}000000000000000000000000${erc1155ContractAddress.substr(
2,
)}${assetDataWithoutContractAddress}`;
///// Step 4/5 /////
// Transfer token IDs [1, 2] and amounts [1, 2] with a multiplier of 2;
// the expected trade will be token IDs [1, 2] and amounts [2, 4]
@@ -805,25 +792,18 @@ describe('ERC1155Proxy', () => {
const tokenUri = '';
for (const tokenToCreate of tokensToCreate) {
// create token
await erc1155Wrapper.getContract().createWithType.awaitTransactionSuccessAsync(
tokenToCreate,
tokenUri,
{
await erc1155Wrapper
.getContract()
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
});
// mint balance for spender
await erc1155Wrapper.getContract().mintFungible.awaitTransactionSuccessAsync(
tokenToCreate,
[spender],
[spenderInitialBalance],
{
await erc1155Wrapper
.getContract()
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
});
}
///// Step 2/5 /////
// Check balances before transfer
@@ -867,7 +847,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [new BigNumber(2), new BigNumber(2)];
const valueMultiplier = new BigNumber(2);
// create callback data that is the encoded version of `valuesToTransfer`
const generatedAssetData = assetDataUtils.encodeERC1155AssetData(
const generatedAssetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -937,25 +917,18 @@ describe('ERC1155Proxy', () => {
const tokenUri = '';
for (const tokenToCreate of tokensToCreate) {
// create token
await erc1155Wrapper.getContract().createWithType.awaitTransactionSuccessAsync(
tokenToCreate,
tokenUri,
{
await erc1155Wrapper
.getContract()
.createWithType.awaitTransactionSuccessAsync(tokenToCreate, tokenUri, {
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
});
// mint balance for spender
await erc1155Wrapper.getContract().mintFungible.awaitTransactionSuccessAsync(
tokenToCreate,
[spender],
[spenderInitialBalance],
{
await erc1155Wrapper
.getContract()
.mintFungible.awaitTransactionSuccessAsync(tokenToCreate, [spender], [spenderInitialBalance], {
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
});
}
///// Step 2/5 /////
// Check balances before transfer
@@ -996,7 +969,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [new BigNumber(1), new BigNumber(2)];
const valueMultiplier = new BigNumber(2);
// create callback data that is the encoded version of `valuesToTransfer`
const generatedAssetData = assetDataUtils.encodeERC1155AssetData(
const generatedAssetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1059,7 +1032,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1106,7 +1079,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1157,7 +1130,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1208,7 +1181,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1259,7 +1232,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1311,7 +1284,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1358,7 +1331,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1409,7 +1382,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1456,7 +1429,7 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -1507,13 +1480,13 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const txData = erc1155ProxyWrapper.getTransferFromAbiEncodedTxData(
const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync(
spender,
receiverContract,
erc1155Contract.address,
@@ -1538,13 +1511,13 @@ describe('ERC1155Proxy', () => {
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
const assetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const txData = erc1155ProxyWrapper.getTransferFromAbiEncodedTxData(
const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync(
spender,
receiverContract,
erc1155Contract.address,
@@ -1667,13 +1640,9 @@ describe('ERC1155Proxy', () => {
it('should propagate revert reason from erc1155 contract failure', async () => {
// disable transfers
const shouldRejectTransfer = true;
await erc1155Receiver.setRejectTransferFlag.awaitTransactionSuccessAsync(
shouldRejectTransfer,
{
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc1155Receiver.setRejectTransferFlag.awaitTransactionSuccessAsync(shouldRejectTransfer, {
from: owner,
});
// setup test parameters
const tokenHolders = [spender, receiverContract];
const tokensToTransfer = fungibleTokens.slice(0, 1);
@@ -1748,9 +1717,14 @@ describe('ERC1155Proxy', () => {
nftNotOwnerBalance,
];
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
const expectedError = new SafeMathRevertErrors.Uint256BinOpError(
SafeMathRevertErrors.BinOpErrorCodes.MultiplicationOverflow,
maxUintValue,
valueMultiplier,
);
// execute transfer
// note - this will overflow because we are trying to transfer `maxUintValue * 2` of the 2nd token
await expectTransactionFailedAsync(
await expect(
erc1155ProxyWrapper.transferFromAsync(
spender,
receiver,
@@ -1761,8 +1735,7 @@ describe('ERC1155Proxy', () => {
receiverCallbackData,
authorized,
),
RevertReason.Uint256Overflow,
);
).to.revertWith(expectedError);
});
it('should revert if transferring > 1 instances of a non-fungible token (valueMultiplier field >1)', async () => {
// setup test parameters
@@ -1832,20 +1805,23 @@ describe('ERC1155Proxy', () => {
// check balances before transfer
const expectedInitialBalances = [spenderInitialFungibleBalance, receiverInitialFungibleBalance];
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
// execute transfer
await expectTransactionFailedAsync(
erc1155ProxyWrapper.transferFromAsync(
spender,
receiver,
erc1155Contract.address,
tokensToTransfer,
valuesToTransfer,
valueMultiplier,
receiverCallbackData,
authorized,
),
RevertReason.Uint256Underflow,
const expectedError = new SafeMathRevertErrors.Uint256BinOpError(
SafeMathRevertErrors.BinOpErrorCodes.SubtractionUnderflow,
spenderInitialFungibleBalance,
valuesToTransfer[0].times(valueMultiplier),
);
// execute transfer
const tx = erc1155ProxyWrapper.transferFromAsync(
spender,
receiver,
erc1155Contract.address,
tokensToTransfer,
valuesToTransfer,
valueMultiplier,
receiverCallbackData,
authorized,
);
return expect(tx).to.revertWith(expectedError);
});
it('should revert if sender allowance is insufficient', async () => {
// dremove allowance for ERC1155 proxy

View File

@@ -0,0 +1,299 @@
import {
blockchainTests,
constants,
expect,
getRandomInteger,
hexLeftPad,
hexRightPad,
hexSlice,
Numberish,
randomAddress,
} from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types';
import { AbiEncoder, AuthorizableRevertErrors, BigNumber, StringRevertError } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import {
artifacts,
ERC20BridgeProxyContract,
TestERC20BridgeBridgeWithdrawToEventArgs,
TestERC20BridgeContract,
} from '../src';
blockchainTests.resets('ERC20BridgeProxy unit tests', env => {
const PROXY_ID = AssetProxyId.ERC20Bridge;
const BRIDGE_SUCCESS_RETURN_DATA = hexRightPad(PROXY_ID);
let owner: string;
let badCaller: string;
let assetProxy: ERC20BridgeProxyContract;
let bridgeContract: TestERC20BridgeContract;
let testTokenAddress: string;
before(async () => {
[owner, badCaller] = await env.getAccountAddressesAsync();
assetProxy = await ERC20BridgeProxyContract.deployFrom0xArtifactAsync(
artifacts.ERC20BridgeProxy,
env.provider,
env.txDefaults,
artifacts,
);
bridgeContract = await TestERC20BridgeContract.deployFrom0xArtifactAsync(
artifacts.TestERC20Bridge,
env.provider,
env.txDefaults,
artifacts,
);
testTokenAddress = await bridgeContract.testToken.callAsync();
await assetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(owner);
});
interface AssetDataOpts {
tokenAddress: string;
bridgeAddress: string;
bridgeData: BridgeDataOpts;
}
interface BridgeDataOpts {
transferAmount: Numberish;
revertError?: string;
returnData: string;
}
function createAssetData(opts?: Partial<AssetDataOpts>): AssetDataOpts {
return _.merge(
{
tokenAddress: testTokenAddress,
bridgeAddress: bridgeContract.address,
bridgeData: createBridgeData(),
},
opts,
);
}
function createBridgeData(opts?: Partial<BridgeDataOpts>): BridgeDataOpts {
return _.merge(
{
transferAmount: constants.ZERO_AMOUNT,
returnData: BRIDGE_SUCCESS_RETURN_DATA,
},
opts,
);
}
function encodeAssetData(opts: AssetDataOpts): string {
const encoder = AbiEncoder.createMethod('ERC20BridgeProxy', [
{ name: 'tokenAddress', type: 'address' },
{ name: 'bridgeAddress', type: 'address' },
{ name: 'bridgeData', type: 'bytes' },
]);
return encoder.encode([opts.tokenAddress, opts.bridgeAddress, encodeBridgeData(opts.bridgeData)]);
}
function encodeBridgeData(opts: BridgeDataOpts): string {
const encoder = AbiEncoder.create([
{ name: 'transferAmount', type: 'int256' },
{ name: 'revertData', type: 'bytes' },
{ name: 'returnData', type: 'bytes' },
]);
const revertErrorBytes =
opts.revertError !== undefined ? new StringRevertError(opts.revertError).encode() : '0x';
return encoder.encode([new BigNumber(opts.transferAmount), revertErrorBytes, opts.returnData]);
}
async function setTestTokenBalanceAsync(_owner: string, balance: Numberish): Promise<void> {
await bridgeContract.setTestTokenBalance.awaitTransactionSuccessAsync(_owner, new BigNumber(balance));
}
describe('transferFrom()', () => {
interface TransferFromOpts {
assetData: AssetDataOpts;
from: string;
to: string;
amount: Numberish;
}
function createTransferFromOpts(opts?: Partial<TransferFromOpts>): TransferFromOpts {
const transferAmount = _.get(opts, ['amount'], getRandomInteger(1, 100e18)) as BigNumber;
return _.merge(
{
assetData: createAssetData({
bridgeData: createBridgeData({
transferAmount,
}),
}),
from: randomAddress(),
to: randomAddress(),
amount: transferAmount,
},
opts,
);
}
async function transferFromAsync(opts?: Partial<TransferFromOpts>, caller?: string): Promise<DecodedLogs> {
const _opts = createTransferFromOpts(opts);
const { logs } = await assetProxy.transferFrom.awaitTransactionSuccessAsync(
encodeAssetData(_opts.assetData),
_opts.from,
_opts.to,
new BigNumber(_opts.amount),
{ from: caller },
);
return (logs as any) as DecodedLogs;
}
it('succeeds if the bridge succeeds and balance increases by `amount`', async () => {
const tx = transferFromAsync();
return expect(tx).to.be.fulfilled('');
});
it('succeeds if balance increases more than `amount`', async () => {
const amount = getRandomInteger(1, 100e18);
const tx = transferFromAsync({
amount,
assetData: createAssetData({
bridgeData: createBridgeData({
transferAmount: amount.plus(1),
}),
}),
});
return expect(tx).to.be.fulfilled('');
});
it('passes the correct arguments to the bridge contract', async () => {
const opts = createTransferFromOpts();
const logs = await transferFromAsync(opts);
expect(logs.length).to.eq(1);
const args = logs[0].args as TestERC20BridgeBridgeWithdrawToEventArgs;
expect(args.tokenAddress).to.eq(opts.assetData.tokenAddress);
expect(args.from).to.eq(opts.from);
expect(args.to).to.eq(opts.to);
expect(args.amount).to.bignumber.eq(opts.amount);
expect(args.bridgeData).to.eq(encodeBridgeData(opts.assetData.bridgeData));
});
it('fails if not called by an authorized address', async () => {
const tx = transferFromAsync({}, badCaller);
return expect(tx).to.revertWith(new AuthorizableRevertErrors.SenderNotAuthorizedError(badCaller));
});
it('fails if asset data is truncated', async () => {
const opts = createTransferFromOpts();
const truncatedAssetData = hexSlice(encodeAssetData(opts.assetData), 0, -1);
const tx = assetProxy.transferFrom.awaitTransactionSuccessAsync(
truncatedAssetData,
opts.from,
opts.to,
new BigNumber(opts.amount),
);
return expect(tx).to.be.rejected();
});
it('fails if bridge returns nothing', async () => {
const tx = transferFromAsync({
assetData: createAssetData({
bridgeData: createBridgeData({
returnData: '0x',
}),
}),
});
// This will actually revert when the AP tries to decode the return
// value.
return expect(tx).to.be.rejected();
});
it('fails if bridge returns true', async () => {
const tx = transferFromAsync({
assetData: createAssetData({
bridgeData: createBridgeData({
returnData: hexLeftPad('0x1'),
}),
}),
});
// This will actually revert when the AP tries to decode the return
// value.
return expect(tx).to.be.rejected();
});
it('fails if bridge returns 0x1', async () => {
const tx = transferFromAsync({
assetData: createAssetData({
bridgeData: createBridgeData({
returnData: hexRightPad('0x1'),
}),
}),
});
return expect(tx).to.revertWith('BRIDGE_FAILED');
});
it('fails if bridge is an EOA', async () => {
const tx = transferFromAsync({
assetData: createAssetData({
bridgeAddress: randomAddress(),
}),
});
// This will actually revert when the AP tries to decode the return
// value.
return expect(tx).to.be.rejected();
});
it('fails if bridge reverts', async () => {
const revertError = 'FOOBAR';
const tx = transferFromAsync({
assetData: createAssetData({
bridgeData: createBridgeData({
revertError,
}),
}),
});
return expect(tx).to.revertWith(revertError);
});
it('fails if balance of `to` increases by less than `amount`', async () => {
const amount = getRandomInteger(1, 100e18);
const tx = transferFromAsync({
amount,
assetData: createAssetData({
bridgeData: createBridgeData({
transferAmount: amount.minus(1),
}),
}),
});
return expect(tx).to.revertWith('BRIDGE_UNDERPAY');
});
it('fails if balance of `to` decreases', async () => {
const toAddress = randomAddress();
await setTestTokenBalanceAsync(toAddress, 1e18);
const tx = transferFromAsync({
to: toAddress,
assetData: createAssetData({
bridgeData: createBridgeData({
transferAmount: -1,
}),
}),
});
return expect(tx).to.revertWith('BRIDGE_UNDERPAY');
});
});
describe('balanceOf()', () => {
it('retrieves the balance of the encoded token', async () => {
const _owner = randomAddress();
const balance = getRandomInteger(1, 100e18);
await bridgeContract.setTestTokenBalance.awaitTransactionSuccessAsync(_owner, balance);
const assetData = createAssetData({
tokenAddress: testTokenAddress,
});
const actualBalance = await assetProxy.balanceOf.callAsync(encodeAssetData(assetData), _owner);
expect(actualBalance).to.bignumber.eq(balance);
});
});
describe('getProxyId()', () => {
it('returns the correct proxy ID', async () => {
const proxyId = await assetProxy.getProxyId.callAsync();
expect(proxyId).to.eq(PROXY_ID);
});
});
});

View File

@@ -0,0 +1,192 @@
import {
blockchainTests,
constants,
expect,
filterLogsToArguments,
getRandomInteger,
hexLeftPad,
hexRandom,
Numberish,
randomAddress,
TransactionHelper,
} from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types';
import { BigNumber, RawRevertError } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import {
artifacts,
TestEth2DaiBridgeContract,
TestEth2DaiBridgeEvents,
TestEth2DaiBridgeSellAllAmountEventArgs,
TestEth2DaiBridgeTokenApproveEventArgs,
TestEth2DaiBridgeTokenTransferEventArgs,
} from '../src';
blockchainTests.resets('Eth2DaiBridge unit tests', env => {
const txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
let testContract: TestEth2DaiBridgeContract;
before(async () => {
testContract = await TestEth2DaiBridgeContract.deployFrom0xArtifactAsync(
artifacts.TestEth2DaiBridge,
env.provider,
env.txDefaults,
artifacts,
);
});
describe('isValidSignature()', () => {
it('returns success bytes', async () => {
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
const result = await testContract.isValidSignature.callAsync(hexRandom(), hexRandom(_.random(0, 32)));
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
});
});
describe('bridgeTransferFrom()', () => {
interface WithdrawToOpts {
toTokenAddress?: string;
fromTokenAddress?: string;
toAddress: string;
amount: Numberish;
fromTokenBalance: Numberish;
revertReason: string;
fillAmount: Numberish;
toTokentransferRevertReason: string;
toTokenTransferReturnData: string;
}
interface WithdrawToResult {
opts: WithdrawToOpts;
result: string;
logs: DecodedLogs;
}
function createWithdrawToOpts(opts?: Partial<WithdrawToOpts>): WithdrawToOpts {
return {
toAddress: randomAddress(),
amount: getRandomInteger(1, 100e18),
revertReason: '',
fillAmount: getRandomInteger(1, 100e18),
fromTokenBalance: getRandomInteger(1, 100e18),
toTokentransferRevertReason: '',
toTokenTransferReturnData: hexLeftPad(1),
...opts,
};
}
async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> {
const _opts = createWithdrawToOpts(opts);
// Set the fill behavior.
await testContract.setFillBehavior.awaitTransactionSuccessAsync(
_opts.revertReason,
new BigNumber(_opts.fillAmount),
);
// Create tokens and balances.
if (_opts.fromTokenAddress === undefined) {
[_opts.fromTokenAddress] = await txHelper.getResultAndReceiptAsync(
testContract.createToken,
new BigNumber(_opts.fromTokenBalance),
);
}
if (_opts.toTokenAddress === undefined) {
[_opts.toTokenAddress] = await txHelper.getResultAndReceiptAsync(
testContract.createToken,
constants.ZERO_AMOUNT,
);
}
// Set the transfer behavior of `toTokenAddress`.
await testContract.setTransferBehavior.awaitTransactionSuccessAsync(
_opts.toTokenAddress,
_opts.toTokentransferRevertReason,
_opts.toTokenTransferReturnData,
);
// Call bridgeTransferFrom().
const [result, { logs }] = await txHelper.getResultAndReceiptAsync(
testContract.bridgeTransferFrom,
// "to" token address
_opts.toTokenAddress,
// Random from address.
randomAddress(),
// To address.
_opts.toAddress,
new BigNumber(_opts.amount),
// ABI-encode the "from" token address as the bridge data.
hexLeftPad(_opts.fromTokenAddress as string),
);
return {
opts: _opts,
result,
logs: (logs as any) as DecodedLogs,
};
}
it('returns magic bytes on success', async () => {
const BRIDGE_SUCCESS_RETURN_DATA = AssetProxyId.ERC20Bridge;
const { result } = await withdrawToAsync();
expect(result).to.eq(BRIDGE_SUCCESS_RETURN_DATA);
});
it('calls `Eth2Dai.sellAllAmount()`', async () => {
const { opts, logs } = await withdrawToAsync();
const transfers = filterLogsToArguments<TestEth2DaiBridgeSellAllAmountEventArgs>(
logs,
TestEth2DaiBridgeEvents.SellAllAmount,
);
expect(transfers.length).to.eq(1);
expect(transfers[0].sellToken).to.eq(opts.fromTokenAddress);
expect(transfers[0].buyToken).to.eq(opts.toTokenAddress);
expect(transfers[0].sellTokenAmount).to.bignumber.eq(opts.fromTokenBalance);
expect(transfers[0].minimumFillAmount).to.bignumber.eq(opts.amount);
});
it('sets an unlimited allowance on the `fromTokenAddress` token', async () => {
const { opts, logs } = await withdrawToAsync();
const approvals = filterLogsToArguments<TestEth2DaiBridgeTokenApproveEventArgs>(
logs,
TestEth2DaiBridgeEvents.TokenApprove,
);
expect(approvals.length).to.eq(1);
expect(approvals[0].token).to.eq(opts.fromTokenAddress);
expect(approvals[0].spender).to.eq(testContract.address);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('transfers filled amount to `to`', async () => {
const { opts, logs } = await withdrawToAsync();
const transfers = filterLogsToArguments<TestEth2DaiBridgeTokenTransferEventArgs>(
logs,
TestEth2DaiBridgeEvents.TokenTransfer,
);
expect(transfers.length).to.eq(1);
expect(transfers[0].token).to.eq(opts.toTokenAddress);
expect(transfers[0].from).to.eq(testContract.address);
expect(transfers[0].to).to.eq(opts.toAddress);
expect(transfers[0].amount).to.bignumber.eq(opts.fillAmount);
});
it('fails if `Eth2Dai.sellAllAmount()` reverts', async () => {
const opts = createWithdrawToOpts({ revertReason: 'FOOBAR' });
const tx = withdrawToAsync(opts);
return expect(tx).to.revertWith(opts.revertReason);
});
it('fails if `toTokenAddress.transfer()` reverts', async () => {
const opts = createWithdrawToOpts({ toTokentransferRevertReason: 'FOOBAR' });
const tx = withdrawToAsync(opts);
return expect(tx).to.revertWith(opts.toTokentransferRevertReason);
});
it('fails if `toTokenAddress.transfer()` returns false', async () => {
const opts = createWithdrawToOpts({ toTokenTransferReturnData: hexLeftPad(0) });
const tx = withdrawToAsync(opts);
return expect(tx).to.revertWith(new RawRevertError(hexLeftPad(0)));
});
it('succeeds if `toTokenAddress.transfer()` returns true', async () => {
await withdrawToAsync({ toTokenTransferReturnData: hexLeftPad(1) });
});
});
});

View File

@@ -1,3 +1,4 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { ERC1155MintableContract, Erc1155Wrapper } from '@0x/contracts-erc1155';
import {
artifacts as erc20Artifacts,
@@ -22,7 +23,6 @@ import {
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 { BigNumber } from '@0x/utils';
import * as chai from 'chai';
@@ -56,6 +56,7 @@ describe('Asset Transfer Proxies', () => {
let fromAddress: string;
let toAddress: string;
let devUtils: DevUtilsContract;
let erc20TokenA: DummyERC20TokenContract;
let erc20TokenB: DummyERC20TokenContract;
let erc721TokenA: DummyERC721TokenContract;
@@ -91,6 +92,7 @@ describe('Asset Transfer Proxies', () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync();
const usedAddresses = ([owner, notAuthorized, authorized, fromAddress, toAddress] = _.slice(accounts, 0, 5));
devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner);
@@ -105,64 +107,24 @@ describe('Asset Transfer Proxies', () => {
);
// Configure ERC20Proxy
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
multiAssetProxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(authorized, { from: owner });
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(multiAssetProxy.address, { from: owner });
// Configure ERC721Proxy
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
multiAssetProxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(authorized, { from: owner });
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(multiAssetProxy.address, { from: owner });
// Configure ERC115Proxy
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
multiAssetProxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(authorized, { from: owner });
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(multiAssetProxy.address, { from: owner });
// Configure MultiAssetProxy
await multiAssetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
authorized,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
erc20Proxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
erc721Proxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
erc1155Proxy.address,
{ from: owner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await multiAssetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(authorized, { from: owner });
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(erc20Proxy.address, { from: owner });
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(erc721Proxy.address, { from: owner });
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(erc1155Proxy.address, { from: owner });
// Deploy and configure ERC20 tokens
const numDummyErc20ToDeploy = 2;
@@ -192,19 +154,13 @@ describe('Asset Transfer Proxies', () => {
);
await erc20Wrapper.setBalancesAndAllowancesAsync();
await noReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
fromAddress,
constants.INITIAL_ERC20_BALANCE,
{
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
await noReturnErc20Token.setBalance.awaitTransactionSuccessAsync(fromAddress, constants.INITIAL_ERC20_BALANCE, {
from: owner,
});
await noReturnErc20Token.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await multipleReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
fromAddress,
@@ -212,13 +168,11 @@ describe('Asset Transfer Proxies', () => {
{
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS,
);
await multipleReturnErc20Token.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
// Deploy and configure ERC721 tokens and receiver
@@ -278,7 +232,7 @@ describe('Asset Transfer Proxies', () => {
describe('transferFrom', () => {
it('should successfully transfer tokens', async () => {
// Construct ERC20 asset data
const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
// Perform a transfer from fromAddress to toAddress
const erc20Balances = await erc20Wrapper.getBalancesAsync();
const amount = new BigNumber(10);
@@ -308,7 +262,7 @@ describe('Asset Transfer Proxies', () => {
it('should successfully transfer tokens that do not return a value', async () => {
// Construct ERC20 asset data
const encodedAssetData = assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address);
const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(noReturnErc20Token.address);
// Perform a transfer from fromAddress to toAddress
const initialFromBalance = await noReturnErc20Token.balanceOf.callAsync(fromAddress);
const initialToBalance = await noReturnErc20Token.balanceOf.callAsync(toAddress);
@@ -337,7 +291,9 @@ describe('Asset Transfer Proxies', () => {
it('should successfully transfer tokens and ignore extra assetData', async () => {
// Construct ERC20 asset data
const extraData = '0102030405060708';
const encodedAssetData = `${assetDataUtils.encodeERC20AssetData(erc20TokenA.address)}${extraData}`;
const encodedAssetData = `${await devUtils.encodeERC20AssetData.callAsync(
erc20TokenA.address,
)}${extraData}`;
// Perform a transfer from fromAddress to toAddress
const erc20Balances = await erc20Wrapper.getBalancesAsync();
const amount = new BigNumber(10);
@@ -367,7 +323,7 @@ describe('Asset Transfer Proxies', () => {
it('should do nothing if transferring 0 amount of a token', async () => {
// Construct ERC20 asset data
const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
// Perform a transfer from fromAddress to toAddress
const erc20Balances = await erc20Wrapper.getBalancesAsync();
const amount = new BigNumber(0);
@@ -397,7 +353,7 @@ describe('Asset Transfer Proxies', () => {
it('should revert if allowances are too low', async () => {
// Construct ERC20 asset data
const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
// Create allowance less than transfer amount. Set allowance on proxy.
const allowance = new BigNumber(0);
const amount = new BigNumber(10);
@@ -407,12 +363,9 @@ describe('Asset Transfer Proxies', () => {
toAddress,
amount,
);
await erc20TokenA.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
allowance,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await erc20TokenA.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: fromAddress,
});
const erc20Balances = await erc20Wrapper.getBalancesAsync();
// Perform a transfer; expect this to fail.
await expectTransactionFailedAsync(
@@ -429,7 +382,7 @@ describe('Asset Transfer Proxies', () => {
it('should revert if allowances are too low and token does not return a value', async () => {
// Construct ERC20 asset data
const encodedAssetData = assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address);
const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(noReturnErc20Token.address);
// Create allowance less than transfer amount. Set allowance on proxy.
const allowance = new BigNumber(0);
const amount = new BigNumber(10);
@@ -439,12 +392,9 @@ describe('Asset Transfer Proxies', () => {
toAddress,
amount,
);
await noReturnErc20Token.approve.awaitTransactionSuccessAsync(
erc20Proxy.address,
allowance,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await noReturnErc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, {
from: fromAddress,
});
const initialFromBalance = await noReturnErc20Token.balanceOf.callAsync(fromAddress);
const initialToBalance = await noReturnErc20Token.balanceOf.callAsync(toAddress);
// Perform a transfer; expect this to fail.
@@ -464,7 +414,7 @@ describe('Asset Transfer Proxies', () => {
it('should revert if caller is not authorized', async () => {
// Construct ERC20 asset data
const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
// Perform a transfer from fromAddress to toAddress
const amount = new BigNumber(10);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
@@ -488,7 +438,9 @@ describe('Asset Transfer Proxies', () => {
it('should revert if token returns more than 32 bytes', async () => {
// Construct ERC20 asset data
const encodedAssetData = assetDataUtils.encodeERC20AssetData(multipleReturnErc20Token.address);
const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(
multipleReturnErc20Token.address,
);
const amount = new BigNumber(10);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
encodedAssetData,
@@ -535,7 +487,10 @@ describe('Asset Transfer Proxies', () => {
describe('transferFrom', () => {
it('should successfully transfer tokens', async () => {
// Construct ERC721 asset data
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
// Verify pre-condition
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
expect(ownerFromAsset).to.be.equal(fromAddress);
@@ -563,7 +518,7 @@ describe('Asset Transfer Proxies', () => {
it('should successfully transfer tokens and ignore extra assetData', async () => {
// Construct ERC721 asset data
const extraData = '0102030405060708';
const encodedAssetData = `${assetDataUtils.encodeERC721AssetData(
const encodedAssetData = `${await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
)}${extraData}`;
@@ -593,7 +548,10 @@ describe('Asset Transfer Proxies', () => {
it('should not call onERC721Received when transferring to a smart contract', async () => {
// Construct ERC721 asset data
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
// Verify pre-condition
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
expect(ownerFromAsset).to.be.equal(fromAddress);
@@ -623,7 +581,10 @@ describe('Asset Transfer Proxies', () => {
it('should revert if transferring 0 amount of a token', async () => {
// Construct ERC721 asset data
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
// Verify pre-condition
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
expect(ownerFromAsset).to.be.equal(fromAddress);
@@ -649,7 +610,10 @@ describe('Asset Transfer Proxies', () => {
it('should revert if transferring > 1 amount of a token', async () => {
// Construct ERC721 asset data
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
// Verify pre-condition
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
expect(ownerFromAsset).to.be.equal(fromAddress);
@@ -675,17 +639,21 @@ describe('Asset Transfer Proxies', () => {
it('should revert if allowances are too low', async () => {
// Construct ERC721 asset data
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
// Verify pre-condition
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
expect(ownerFromAsset).to.be.equal(fromAddress);
// Remove transfer approval for fromAddress.
await erc721TokenA.approve.awaitTransactionSuccessAsync(
constants.NULL_ADDRESS,
erc721AFromTokenId,
{ from: fromAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
// Remove blanket transfer approval for fromAddress.
await erc721TokenA.setApprovalForAll.awaitTransactionSuccessAsync(erc721Proxy.address, false, {
from: fromAddress,
});
// Remove token transfer approval for fromAddress.
await erc721TokenA.approve.awaitTransactionSuccessAsync(constants.NULL_ADDRESS, erc721AFromTokenId, {
from: fromAddress,
});
// Perform a transfer; expect this to fail.
const amount = new BigNumber(1);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
@@ -708,7 +676,10 @@ describe('Asset Transfer Proxies', () => {
it('should revert if caller is not authorized', async () => {
// Construct ERC721 asset data
const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
// Verify pre-condition
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
expect(ownerFromAsset).to.be.equal(fromAddress);
@@ -755,10 +726,10 @@ describe('Asset Transfer Proxies', () => {
it('should transfer a single ERC20 token', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const amounts = [erc20Amount];
const nestedAssetData = [erc20AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -786,7 +757,7 @@ describe('Asset Transfer Proxies', () => {
it('should dispatch an ERC20 transfer when input amount is 0', async () => {
const inputAmount = constants.ZERO_AMOUNT;
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const amounts = [erc20Amount];
const nestedAssetData = [erc20AssetData];
const assetData = assetDataInterface.MultiAsset.getABIEncodedTransactionData(amounts, nestedAssetData);
@@ -817,11 +788,11 @@ describe('Asset Transfer Proxies', () => {
const inputAmount = new BigNumber(1);
const erc20Amount1 = new BigNumber(10);
const erc20Amount2 = new BigNumber(20);
const erc20AssetData1 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData1 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const amounts = [erc20Amount1, erc20Amount2];
const nestedAssetData = [erc20AssetData1, erc20AssetData2];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -850,11 +821,11 @@ describe('Asset Transfer Proxies', () => {
const inputAmount = new BigNumber(1);
const erc20Amount1 = new BigNumber(10);
const erc20Amount2 = new BigNumber(20);
const erc20AssetData1 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20TokenB.address);
const erc20AssetData1 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address);
const amounts = [erc20Amount1, erc20Amount2];
const nestedAssetData = [erc20AssetData1, erc20AssetData2];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -889,10 +860,13 @@ describe('Asset Transfer Proxies', () => {
it('should transfer a single ERC721 token', async () => {
const inputAmount = new BigNumber(1);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc721Amount];
const nestedAssetData = [erc721AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -915,8 +889,11 @@ describe('Asset Transfer Proxies', () => {
it('should successfully transfer multiple of the same ERC721 token', async () => {
const erc721Balances = await erc721Wrapper.getBalancesAsync();
const erc721AFromTokenId2 = erc721Balances[fromAddress][erc721TokenA.address][1];
const erc721AssetData1 = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData2 = assetDataUtils.encodeERC721AssetData(
const erc721AssetData1 = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const erc721AssetData2 = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId2,
);
@@ -924,7 +901,7 @@ describe('Asset Transfer Proxies', () => {
const erc721Amount = new BigNumber(1);
const amounts = [erc721Amount, erc721Amount];
const nestedAssetData = [erc721AssetData1, erc721AssetData2];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -950,13 +927,19 @@ describe('Asset Transfer Proxies', () => {
expect(newOwnerFromAsset2).to.be.equal(toAddress);
});
it('should successfully transfer multiple different ERC721 tokens', async () => {
const erc721AssetData1 = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData2 = assetDataUtils.encodeERC721AssetData(erc721TokenB.address, erc721BFromTokenId);
const erc721AssetData1 = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const erc721AssetData2 = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenB.address,
erc721BFromTokenId,
);
const inputAmount = new BigNumber(1);
const erc721Amount = new BigNumber(1);
const amounts = [erc721Amount, erc721Amount];
const nestedAssetData = [erc721AssetData1, erc721AssetData2];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -997,7 +980,7 @@ describe('Asset Transfer Proxies', () => {
];
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
// encode erc1155 asset data
const erc1155AssetData = assetDataUtils.encodeERC1155AssetData(
const erc1155AssetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155Contract.address,
tokensToTransfer,
valuesToTransfer,
@@ -1007,7 +990,7 @@ describe('Asset Transfer Proxies', () => {
const multiAssetAmount = new BigNumber(5);
const amounts = [valueMultiplier];
const nestedAssetData = [erc1155AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1053,7 +1036,7 @@ describe('Asset Transfer Proxies', () => {
];
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
// encode erc1155 asset data
const erc1155AssetData = assetDataUtils.encodeERC1155AssetData(
const erc1155AssetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155Contract.address,
tokensToTransfer,
valuesToTransfer,
@@ -1063,7 +1046,7 @@ describe('Asset Transfer Proxies', () => {
const multiAssetAmount = new BigNumber(5);
const amounts = [valueMultiplier];
const nestedAssetData = [erc1155AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1117,7 +1100,7 @@ describe('Asset Transfer Proxies', () => {
];
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
// encode erc1155 asset data
const erc1155AssetData = assetDataUtils.encodeERC1155AssetData(
const erc1155AssetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155Contract.address,
tokensToTransfer,
valuesToTransfer,
@@ -1127,7 +1110,7 @@ describe('Asset Transfer Proxies', () => {
const multiAssetAmount = new BigNumber(1);
const amounts = [valueMultiplier];
const nestedAssetData = [erc1155AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1174,13 +1157,13 @@ describe('Asset Transfer Proxies', () => {
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
await erc1155Wrapper2.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
// encode erc1155 asset data
const erc1155AssetData1 = assetDataUtils.encodeERC1155AssetData(
const erc1155AssetData1 = await devUtils.encodeERC1155AssetData.callAsync(
erc1155Contract.address,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const erc1155AssetData2 = assetDataUtils.encodeERC1155AssetData(
const erc1155AssetData2 = await devUtils.encodeERC1155AssetData.callAsync(
erc1155Contract2.address,
tokensToTransfer,
valuesToTransfer,
@@ -1190,7 +1173,7 @@ describe('Asset Transfer Proxies', () => {
const multiAssetAmount = new BigNumber(5);
const amounts = [valueMultiplier, valueMultiplier];
const nestedAssetData = [erc1155AssetData1, erc1155AssetData2];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1221,15 +1204,18 @@ describe('Asset Transfer Proxies', () => {
// setup test parameters
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const erc1155TokenHolders = [fromAddress, toAddress];
const erc1155TokensToTransfer = erc1155FungibleTokens.slice(0, 1);
const erc1155ValuesToTransfer = [new BigNumber(25)];
const erc1155Amount = new BigNumber(23);
const erc1155ReceiverCallbackData = '0x0102030405';
const erc1155AssetData = assetDataUtils.encodeERC1155AssetData(
const erc1155AssetData = await devUtils.encodeERC1155AssetData.callAsync(
erc1155Contract.address,
erc1155TokensToTransfer,
erc1155ValuesToTransfer,
@@ -1237,7 +1223,7 @@ describe('Asset Transfer Proxies', () => {
);
const amounts = [erc20Amount, erc721Amount, erc1155Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData, erc1155AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1292,12 +1278,15 @@ describe('Asset Transfer Proxies', () => {
it('should successfully transfer a combination of ERC20 and ERC721 tokens', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1329,13 +1318,19 @@ describe('Asset Transfer Proxies', () => {
it('should successfully transfer tokens and ignore extra assetData', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
const extraData = '0102030405060708090001020304050607080900010203040506070809000102';
const assetData = `${assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData)}${extraData}`;
const assetData = `${await devUtils.encodeMultiAssetData.callAsync(
amounts,
nestedAssetData,
)}${extraData}`;
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1368,11 +1363,11 @@ describe('Asset Transfer Proxies', () => {
const inputAmount = new BigNumber(100);
const erc20Amount1 = new BigNumber(10);
const erc20Amount2 = new BigNumber(20);
const erc20AssetData1 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20TokenB.address);
const erc20AssetData1 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address);
const amounts = [erc20Amount1, erc20Amount2];
const nestedAssetData = [erc20AssetData1, erc20AssetData2];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1408,19 +1403,25 @@ describe('Asset Transfer Proxies', () => {
const inputAmount = new BigNumber(1);
const erc20Amount1 = new BigNumber(10);
const erc20Amount2 = new BigNumber(20);
const erc20AssetData1 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20TokenB.address);
const erc20AssetData1 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address);
const erc721Amount = new BigNumber(1);
const erc721Balances = await erc721Wrapper.getBalancesAsync();
const erc721AFromTokenId2 = erc721Balances[fromAddress][erc721TokenA.address][1];
const erc721BFromTokenId2 = erc721Balances[fromAddress][erc721TokenB.address][1];
const erc721AssetData1 = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData2 = assetDataUtils.encodeERC721AssetData(
const erc721AssetData1 = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const erc721AssetData2 = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId2,
);
const erc721AssetData3 = assetDataUtils.encodeERC721AssetData(erc721TokenB.address, erc721BFromTokenId);
const erc721AssetData4 = assetDataUtils.encodeERC721AssetData(
const erc721AssetData3 = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenB.address,
erc721BFromTokenId,
);
const erc721AssetData4 = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenB.address,
erc721BFromTokenId2,
);
@@ -1433,7 +1434,7 @@ describe('Asset Transfer Proxies', () => {
erc721AssetData3,
erc721AssetData4,
];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1485,13 +1486,16 @@ describe('Asset Transfer Proxies', () => {
it('should revert if a single transfer fails', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
// 2 is an invalid erc721 amount
const erc721Amount = new BigNumber(2);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1510,15 +1514,17 @@ describe('Asset Transfer Proxies', () => {
it('should revert if an AssetProxy is not registered', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const invalidProxyId = '0x12345678';
const invalidErc721AssetData = `${invalidProxyId}${erc721AssetData.slice(10)}`;
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, invalidErc721AssetData];
// HACK: This is used to get around validation built into assetDataUtils
const assetData = assetDataInterface.MultiAsset.getABIEncodedTransactionData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1537,12 +1543,14 @@ describe('Asset Transfer Proxies', () => {
it('should revert if the length of `amounts` does not match the length of `nestedAssetData`', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc20Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
// HACK: This is used to get around validation built into assetDataUtils
const assetData = assetDataInterface.MultiAsset.getABIEncodedTransactionData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1561,10 +1569,10 @@ describe('Asset Transfer Proxies', () => {
it('should revert if amounts multiplication results in an overflow', async () => {
const inputAmount = new BigNumber(2).pow(128);
const erc20Amount = new BigNumber(2).pow(128);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const amounts = [erc20Amount];
const nestedAssetData = [erc20AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1583,13 +1591,12 @@ describe('Asset Transfer Proxies', () => {
it('should revert if an element of `nestedAssetData` is < 4 bytes long', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = '0x123456';
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
// HACK: This is used to get around validation built into assetDataUtils
const assetData = assetDataInterface.MultiAsset.getABIEncodedTransactionData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1608,12 +1615,15 @@ describe('Asset Transfer Proxies', () => {
it('should revert if caller is not authorized', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1632,12 +1642,15 @@ describe('Asset Transfer Proxies', () => {
it('should revert if asset data overflows beyond the bounds of calldata', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1662,12 +1675,15 @@ describe('Asset Transfer Proxies', () => {
it('should revert if asset data resolves to a location beyond the bounds of calldata', async () => {
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
assetData,
fromAddress,
@@ -1693,12 +1709,15 @@ describe('Asset Transfer Proxies', () => {
// setup test parameters
const inputAmount = new BigNumber(1);
const erc20Amount = new BigNumber(10);
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address);
const erc721Amount = new BigNumber(1);
const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId);
const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(
erc721TokenA.address,
erc721AFromTokenId,
);
const amounts = [erc20Amount, erc721Amount];
const nestedAssetData = [erc20AssetData, erc721AssetData];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData);
const extraData = '01';
const assetDataWithExtraData = `${assetData}${extraData}`;
const badData = assetProxyInterface.transferFrom.getABIEncodedTransactionData(

View File

@@ -1,3 +1,4 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import {
chaiSetup,
constants,
@@ -8,7 +9,6 @@ import {
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';
@@ -25,6 +25,7 @@ describe('StaticCallProxy', () => {
let fromAddress: string;
let toAddress: string;
let devUtils: DevUtilsContract;
let staticCallProxy: IAssetProxyContract;
let staticCallTarget: TestStaticCallTargetContract;
@@ -43,7 +44,14 @@ describe('StaticCallProxy', () => {
txDefaults,
artifacts,
);
staticCallProxy = new IAssetProxyContract(staticCallProxyWithoutTransferFrom.address, provider, txDefaults);
devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
staticCallProxy = new IAssetProxyContract(
staticCallProxyWithoutTransferFrom.address,
provider,
txDefaults,
{},
StaticCallProxyContract.deployedBytecode,
);
staticCallTarget = await TestStaticCallTargetContract.deployFrom0xArtifactAsync(
artifacts.TestStaticCallTarget,
provider,
@@ -80,7 +88,7 @@ describe('StaticCallProxy', () => {
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(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
@@ -108,9 +116,11 @@ describe('StaticCallProxy', () => {
it('should revert if the length of assetData is less than 100 bytes', async () => {
const staticCallData = constants.NULL_BYTES;
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils
.encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash)
.slice(0, -128);
const assetData = (await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
)).slice(0, -128);
const assetDataByteLen = (assetData.length - 2) / 2;
expect((assetDataByteLen - 4) % 32).to.equal(0);
await expectTransactionFailedWithoutReasonAsync(
@@ -120,7 +130,7 @@ describe('StaticCallProxy', () => {
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(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
@@ -141,7 +151,7 @@ describe('StaticCallProxy', () => {
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(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
@@ -153,7 +163,7 @@ describe('StaticCallProxy', () => {
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(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
@@ -167,7 +177,7 @@ describe('StaticCallProxy', () => {
const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0));
const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001');
const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer));
const assetData = assetDataUtils.encodeStaticCallAssetData(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
@@ -180,7 +190,7 @@ describe('StaticCallProxy', () => {
it('should be successful if a function call with no inputs and no outputs is successful', async () => {
const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData();
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
@@ -190,14 +200,18 @@ describe('StaticCallProxy', () => {
it('should be successful if the staticCallTarget is not a contract and no return value is expected', async () => {
const staticCallData = '0x0102030405060708';
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(toAddress, staticCallData, expectedResultHash);
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
toAddress,
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(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
@@ -208,7 +222,7 @@ describe('StaticCallProxy', () => {
const dynamicInput = '0x0102030405060708';
const staticCallData = staticCallTarget.dynamicInputFunction.getABIEncodedTransactionData(dynamicInput);
const expectedResultHash = constants.KECCAK256_NULL;
const assetData = assetDataUtils.encodeStaticCallAssetData(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,
@@ -231,7 +245,7 @@ describe('StaticCallProxy', () => {
const expectedResultHash = ethUtil.bufferToHex(
ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)),
);
const assetData = assetDataUtils.encodeStaticCallAssetData(
const assetData = await devUtils.encodeStaticCallAssetData.callAsync(
staticCallTarget.address,
staticCallData,
expectedResultHash,

View File

@@ -0,0 +1,365 @@
import {
blockchainTests,
constants,
expect,
filterLogs,
filterLogsToArguments,
getRandomInteger,
hexLeftPad,
hexRandom,
Numberish,
randomAddress,
TransactionHelper,
} from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { DecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import {
artifacts,
TestUniswapBridgeContract,
TestUniswapBridgeEthToTokenTransferInputEventArgs as EthToTokenTransferInputArgs,
TestUniswapBridgeEvents as ContractEvents,
TestUniswapBridgeTokenApproveEventArgs as TokenApproveArgs,
TestUniswapBridgeTokenToEthSwapInputEventArgs as TokenToEthSwapInputArgs,
TestUniswapBridgeTokenToTokenTransferInputEventArgs as TokenToTokenTransferInputArgs,
TestUniswapBridgeTokenTransferEventArgs as TokenTransferArgs,
TestUniswapBridgeWethDepositEventArgs as WethDepositArgs,
TestUniswapBridgeWethWithdrawEventArgs as WethWithdrawArgs,
} from '../src';
blockchainTests.resets('UniswapBridge unit tests', env => {
const txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
let testContract: TestUniswapBridgeContract;
let wethTokenAddress: string;
before(async () => {
testContract = await TestUniswapBridgeContract.deployFrom0xArtifactAsync(
artifacts.TestUniswapBridge,
env.provider,
env.txDefaults,
artifacts,
);
wethTokenAddress = await testContract.wethToken.callAsync();
});
describe('isValidSignature()', () => {
it('returns success bytes', async () => {
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
const result = await testContract.isValidSignature.callAsync(hexRandom(), hexRandom(_.random(0, 32)));
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
});
});
describe('bridgeTransferFrom()', () => {
interface WithdrawToOpts {
fromTokenAddress: string;
toTokenAddress: string;
fromTokenBalance: Numberish;
toAddress: string;
amount: Numberish;
exchangeRevertReason: string;
exchangeFillAmount: Numberish;
toTokenRevertReason: string;
fromTokenRevertReason: string;
}
function createWithdrawToOpts(opts?: Partial<WithdrawToOpts>): WithdrawToOpts {
return {
fromTokenAddress: constants.NULL_ADDRESS,
toTokenAddress: constants.NULL_ADDRESS,
fromTokenBalance: getRandomInteger(1, 1e18),
toAddress: randomAddress(),
amount: getRandomInteger(1, 1e18),
exchangeRevertReason: '',
exchangeFillAmount: getRandomInteger(1, 1e18),
toTokenRevertReason: '',
fromTokenRevertReason: '',
...opts,
};
}
interface WithdrawToResult {
opts: WithdrawToOpts;
result: string;
logs: DecodedLogs;
blockTime: number;
}
async function withdrawToAsync(opts?: Partial<WithdrawToOpts>): Promise<WithdrawToResult> {
const _opts = createWithdrawToOpts(opts);
// Create the "from" token and exchange.
[[_opts.fromTokenAddress]] = await txHelper.getResultAndReceiptAsync(
testContract.createTokenAndExchange,
_opts.fromTokenAddress,
_opts.exchangeRevertReason,
{ value: new BigNumber(_opts.exchangeFillAmount) },
);
// Create the "to" token and exchange.
[[_opts.toTokenAddress]] = await txHelper.getResultAndReceiptAsync(
testContract.createTokenAndExchange,
_opts.toTokenAddress,
_opts.exchangeRevertReason,
{ value: new BigNumber(_opts.exchangeFillAmount) },
);
await testContract.setTokenRevertReason.awaitTransactionSuccessAsync(
_opts.toTokenAddress,
_opts.toTokenRevertReason,
);
await testContract.setTokenRevertReason.awaitTransactionSuccessAsync(
_opts.fromTokenAddress,
_opts.fromTokenRevertReason,
);
// Set the token balance for the token we're converting from.
await testContract.setTokenBalance.awaitTransactionSuccessAsync(_opts.fromTokenAddress, {
value: new BigNumber(_opts.fromTokenBalance),
});
// Call bridgeTransferFrom().
const [result, receipt] = await txHelper.getResultAndReceiptAsync(
testContract.bridgeTransferFrom,
// The "to" token address.
_opts.toTokenAddress,
// The "from" address.
randomAddress(),
// The "to" address.
_opts.toAddress,
// The amount to transfer to "to"
new BigNumber(_opts.amount),
// ABI-encoded "from" token address.
hexLeftPad(_opts.fromTokenAddress),
);
return {
opts: _opts,
result,
logs: (receipt.logs as any) as DecodedLogs,
blockTime: await env.web3Wrapper.getBlockTimestampAsync(receipt.blockNumber),
};
}
async function getExchangeForTokenAsync(tokenAddress: string): Promise<string> {
return testContract.getExchange.callAsync(tokenAddress);
}
it('returns magic bytes on success', async () => {
const { result } = await withdrawToAsync();
expect(result).to.eq(AssetProxyId.ERC20Bridge);
});
it('just transfers tokens to `to` if the same tokens are in play', async () => {
const [[tokenAddress]] = await txHelper.getResultAndReceiptAsync(
testContract.createTokenAndExchange,
constants.NULL_ADDRESS,
'',
);
const { opts, result, logs } = await withdrawToAsync({
fromTokenAddress: tokenAddress,
toTokenAddress: tokenAddress,
});
expect(result).to.eq(AssetProxyId.ERC20Bridge);
const transfers = filterLogsToArguments<TokenTransferArgs>(logs, ContractEvents.TokenTransfer);
expect(transfers.length).to.eq(1);
expect(transfers[0].token).to.eq(tokenAddress);
expect(transfers[0].from).to.eq(testContract.address);
expect(transfers[0].to).to.eq(opts.toAddress);
expect(transfers[0].amount).to.bignumber.eq(opts.amount);
});
describe('token -> token', () => {
it('calls `IUniswapExchange.tokenToTokenTransferInput()', async () => {
const { opts, logs, blockTime } = await withdrawToAsync();
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
const calls = filterLogsToArguments<TokenToTokenTransferInputArgs>(
logs,
ContractEvents.TokenToTokenTransferInput,
);
expect(calls.length).to.eq(1);
expect(calls[0].exchange).to.eq(exchangeAddress);
expect(calls[0].tokensSold).to.bignumber.eq(opts.fromTokenBalance);
expect(calls[0].minTokensBought).to.bignumber.eq(opts.amount);
expect(calls[0].minEthBought).to.bignumber.eq(0);
expect(calls[0].deadline).to.bignumber.eq(blockTime);
expect(calls[0].recipient).to.eq(opts.toAddress);
expect(calls[0].toTokenAddress).to.eq(opts.toTokenAddress);
});
it('sets allowance for "from" token', async () => {
const { opts, logs } = await withdrawToAsync();
const approvals = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(approvals.length).to.eq(1);
expect(approvals[0].spender).to.eq(exchangeAddress);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('sets allowance for "from" token on subsequent calls', async () => {
const { opts } = await withdrawToAsync();
const { logs } = await withdrawToAsync(opts);
const approvals = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(approvals.length).to.eq(1);
expect(approvals[0].spender).to.eq(exchangeAddress);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('fails if "from" token does not exist', async () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
randomAddress(),
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(randomAddress()),
);
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
});
it('fails if the exchange fails', async () => {
const revertReason = 'FOOBAR';
const tx = withdrawToAsync({
exchangeRevertReason: revertReason,
});
return expect(tx).to.revertWith(revertReason);
});
});
describe('token -> ETH', () => {
it('calls `IUniswapExchange.tokenToEthSwapInput()`, `WETH.deposit()`, then `transfer()`', async () => {
const { opts, logs, blockTime } = await withdrawToAsync({
toTokenAddress: wethTokenAddress,
});
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
let calls: any = filterLogs<TokenToEthSwapInputArgs>(logs, ContractEvents.TokenToEthSwapInput);
expect(calls.length).to.eq(1);
expect(calls[0].args.exchange).to.eq(exchangeAddress);
expect(calls[0].args.tokensSold).to.bignumber.eq(opts.fromTokenBalance);
expect(calls[0].args.minEthBought).to.bignumber.eq(opts.amount);
expect(calls[0].args.deadline).to.bignumber.eq(blockTime);
calls = filterLogs<WethDepositArgs>(
logs.slice(calls[0].logIndex as number),
ContractEvents.WethDeposit,
);
expect(calls.length).to.eq(1);
expect(calls[0].args.amount).to.bignumber.eq(opts.exchangeFillAmount);
calls = filterLogs<TokenTransferArgs>(
logs.slice(calls[0].logIndex as number),
ContractEvents.TokenTransfer,
);
expect(calls.length).to.eq(1);
expect(calls[0].args.token).to.eq(opts.toTokenAddress);
expect(calls[0].args.from).to.eq(testContract.address);
expect(calls[0].args.to).to.eq(opts.toAddress);
expect(calls[0].args.amount).to.bignumber.eq(opts.exchangeFillAmount);
});
it('sets allowance for "from" token', async () => {
const { opts, logs } = await withdrawToAsync({
toTokenAddress: wethTokenAddress,
});
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(transfers.length).to.eq(1);
expect(transfers[0].spender).to.eq(exchangeAddress);
expect(transfers[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('sets allowance for "from" token on subsequent calls', async () => {
const { opts } = await withdrawToAsync({
toTokenAddress: wethTokenAddress,
});
const { logs } = await withdrawToAsync(opts);
const approvals = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(approvals.length).to.eq(1);
expect(approvals[0].spender).to.eq(exchangeAddress);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('fails if "from" token does not exist', async () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
randomAddress(),
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(wethTokenAddress),
);
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
});
it('fails if `WETH.deposit()` fails', async () => {
const revertReason = 'FOOBAR';
const tx = withdrawToAsync({
toTokenAddress: wethTokenAddress,
toTokenRevertReason: revertReason,
});
return expect(tx).to.revertWith(revertReason);
});
it('fails if the exchange fails', async () => {
const revertReason = 'FOOBAR';
const tx = withdrawToAsync({
toTokenAddress: wethTokenAddress,
exchangeRevertReason: revertReason,
});
return expect(tx).to.revertWith(revertReason);
});
});
describe('ETH -> token', () => {
it('calls `WETH.withdraw()`, then `IUniswapExchange.ethToTokenTransferInput()`', async () => {
const { opts, logs, blockTime } = await withdrawToAsync({
fromTokenAddress: wethTokenAddress,
});
const exchangeAddress = await getExchangeForTokenAsync(opts.toTokenAddress);
let calls: any = filterLogs<WethWithdrawArgs>(logs, ContractEvents.WethWithdraw);
expect(calls.length).to.eq(1);
expect(calls[0].args.amount).to.bignumber.eq(opts.fromTokenBalance);
calls = filterLogs<EthToTokenTransferInputArgs>(
logs.slice(calls[0].logIndex as number),
ContractEvents.EthToTokenTransferInput,
);
expect(calls.length).to.eq(1);
expect(calls[0].args.exchange).to.eq(exchangeAddress);
expect(calls[0].args.minTokensBought).to.bignumber.eq(opts.amount);
expect(calls[0].args.deadline).to.bignumber.eq(blockTime);
expect(calls[0].args.recipient).to.eq(opts.toAddress);
});
it('does not set any allowance', async () => {
const { logs } = await withdrawToAsync({
fromTokenAddress: wethTokenAddress,
});
const approvals = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
expect(approvals).to.be.empty('');
});
it('fails if "to" token does not exist', async () => {
const tx = testContract.bridgeTransferFrom.awaitTransactionSuccessAsync(
wethTokenAddress,
randomAddress(),
randomAddress(),
getRandomInteger(1, 1e18),
hexLeftPad(randomAddress()),
);
return expect(tx).to.revertWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN');
});
it('fails if the `WETH.withdraw()` fails', async () => {
const revertReason = 'FOOBAR';
const tx = withdrawToAsync({
fromTokenAddress: wethTokenAddress,
fromTokenRevertReason: revertReason,
});
return expect(tx).to.revertWith(revertReason);
});
it('fails if the exchange fails', async () => {
const revertReason = 'FOOBAR';
const tx = withdrawToAsync({
fromTokenAddress: wethTokenAddress,
exchangeRevertReason: revertReason,
});
return expect(tx).to.revertWith(revertReason);
});
});
});
});

View File

@@ -1,3 +1,4 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { artifacts as erc1155Artifacts, ERC1155MintableContract, Erc1155Wrapper } from '@0x/contracts-erc1155';
import {
constants,
@@ -7,7 +8,6 @@ import {
LogDecoder,
txDefaults,
} from '@0x/contracts-test-utils';
import { assetDataUtils } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
@@ -26,6 +26,7 @@ export class ERC1155ProxyWrapper {
private readonly _logDecoder: LogDecoder;
private readonly _dummyTokenWrappers: Erc1155Wrapper[];
private readonly _assetProxyInterface: IAssetProxyContract;
private readonly _devUtils: DevUtilsContract;
private _proxyContract?: ERC1155ProxyContract;
private _proxyIdIfExists?: string;
private _initialTokenIdsByOwner: ERC1155HoldingsByOwner = { fungible: {}, nonFungible: {} };
@@ -37,6 +38,7 @@ export class ERC1155ProxyWrapper {
this._logDecoder = new LogDecoder(this._web3Wrapper, allArtifacts);
this._dummyTokenWrappers = [];
this._assetProxyInterface = new IAssetProxyContract(constants.NULL_ADDRESS, provider);
this._devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
this._tokenOwnerAddresses = tokenOwnerAddresses;
this._contractOwnerAddress = contractOwnerAddress;
this._fungibleTokenIds = [];
@@ -95,7 +97,7 @@ export class ERC1155ProxyWrapper {
* @param extraData extra data to append to `transferFrom` transaction. Optional.
* @return abi encoded tx data.
*/
public getTransferFromAbiEncodedTxData(
public async getTransferFromAbiEncodedTxDataAsync(
from: string,
to: string,
contractAddress: string,
@@ -105,11 +107,11 @@ export class ERC1155ProxyWrapper {
receiverCallbackData: string,
authorizedSender: string,
assetData_?: string,
): string {
): Promise<string> {
this._validateProxyContractExistsOrThrow();
const assetData =
assetData_ === undefined
? assetDataUtils.encodeERC1155AssetData(
? await this._devUtils.encodeERC1155AssetData.callAsync(
contractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -169,7 +171,7 @@ export class ERC1155ProxyWrapper {
this._validateProxyContractExistsOrThrow();
const assetData =
assetData_ === undefined
? assetDataUtils.encodeERC1155AssetData(
? await this._devUtils.encodeERC1155AssetData.callAsync(
contractAddress,
tokensToTransfer,
valuesToTransfer,
@@ -336,6 +338,22 @@ export class ERC1155ProxyWrapper {
};
return holdingsByOwner;
}
/**
* @dev Set the approval for the proxy on behalf of `userAddress` .
* @param userAddress owner of ERC1155 tokens.
* @param contractAddress address of ERC1155 contract.
* @param isApproved Whether to approve the proxy for all or not.
*/
public async setProxyAllowanceForAllAsync(
userAddress: string,
contractAddress: string,
isApproved: boolean,
): Promise<void> {
this._validateProxyContractExistsOrThrow();
const tokenWrapper = this.getContractWrapper(contractAddress);
const operator = (this._proxyContract as ERC1155ProxyContract).address;
await tokenWrapper.setApprovalForAllAsync(userAddress, operator, isApproved);
}
/**
* @dev Checks if proxy is approved to transfer tokens on behalf of `userAddress`.
* @param userAddress owner of ERC1155 tokens.

View File

@@ -1,6 +1,6 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20';
import { constants, ERC20BalancesByOwner, txDefaults } from '@0x/contracts-test-utils';
import { assetDataUtils } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import { ZeroExProvider } from 'ethereum-types';
import * as _ from 'lodash';
@@ -12,6 +12,7 @@ export class ERC20Wrapper {
private readonly _contractOwnerAddress: string;
private readonly _provider: ZeroExProvider;
private readonly _dummyTokenContracts: DummyERC20TokenContract[];
private readonly _devUtils: DevUtilsContract;
private _proxyContract?: ERC20ProxyContract;
private _proxyIdIfExists?: string;
/**
@@ -26,6 +27,7 @@ export class ERC20Wrapper {
this._provider = provider;
this._tokenOwnerAddresses = tokenOwnerAddresses;
this._contractOwnerAddress = contractOwnerAddress;
this._devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
}
public async deployDummyTokensAsync(
numberToDeploy: number,
@@ -70,46 +72,39 @@ export class ERC20Wrapper {
tokenOwnerAddress,
constants.INITIAL_ERC20_BALANCE,
{ from: this._contractOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await dummyTokenContract.approve.awaitTransactionSuccessAsync(
(this._proxyContract as ERC20ProxyContract).address,
constants.INITIAL_ERC20_ALLOWANCE,
{ from: tokenOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
}
}
}
public async getBalanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
const tokenContract = this._getTokenContractFromAssetData(assetData);
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
const balance = new BigNumber(await tokenContract.balanceOf.callAsync(userAddress));
return balance;
}
public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(assetData);
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
await tokenContract.setBalance.awaitTransactionSuccessAsync(
userAddress,
amount,
{ from: this._contractOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
{ pollingIntervalMs: constants.AWAIT_TRANSACTION_MINED_MS },
);
}
public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
const tokenContract = this._getTokenContractFromAssetData(assetData);
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
const allowance = new BigNumber(await tokenContract.allowance.callAsync(userAddress, proxyAddress));
return allowance;
}
public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(assetData);
const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData);
const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
await tokenContract.approve.awaitTransactionSuccessAsync(
proxyAddress,
amount,
{ from: userAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await tokenContract.approve.awaitTransactionSuccessAsync(proxyAddress, amount, { from: userAddress });
}
public async getBalancesAsync(): Promise<ERC20BalancesByOwner> {
this._validateDummyTokenContractsExistOrThrow();
@@ -151,9 +146,8 @@ export class ERC20Wrapper {
const tokenAddresses = _.map(this._dummyTokenContracts, dummyTokenContract => dummyTokenContract.address);
return tokenAddresses;
}
private _getTokenContractFromAssetData(assetData: string): DummyERC20TokenContract {
const erc20ProxyData = assetDataUtils.decodeERC20AssetData(assetData);
const tokenAddress = erc20ProxyData.tokenAddress;
private async _getTokenContractFromAssetDataAsync(assetData: string): Promise<DummyERC20TokenContract> {
const [proxyId, tokenAddress] = await this._devUtils.decodeERC20AssetData.callAsync(assetData); // tslint:disable-line:no-unused-variable
const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
if (tokenContractIfExists === undefined) {
throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);

View File

@@ -71,7 +71,7 @@ export class ERC721Wrapper {
}
this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address].push(tokenId);
await this.approveProxyAsync(dummyTokenContract.address, tokenId);
await this.approveProxyForAllAsync(dummyTokenContract.address, tokenOwnerAddress, true);
}
}
}
@@ -86,26 +86,21 @@ export class ERC721Wrapper {
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
await this.approveAsync(proxyAddress, tokenAddress, tokenId);
}
public async approveProxyForAllAsync(tokenAddress: string, tokenId: BigNumber, isApproved: boolean): Promise<void> {
public async approveProxyForAllAsync(
tokenAddress: string,
ownerAddress: string,
isApproved: boolean,
): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
await tokenContract.setApprovalForAll.awaitTransactionSuccessAsync(
proxyAddress,
isApproved,
{ from: tokenOwner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await tokenContract.setApprovalForAll.awaitTransactionSuccessAsync(proxyAddress, isApproved, {
from: ownerAddress,
});
}
public async approveAsync(to: string, tokenAddress: string, tokenId: BigNumber): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
await tokenContract.approve.awaitTransactionSuccessAsync(
to,
tokenId,
{ from: tokenOwner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await tokenContract.approve.awaitTransactionSuccessAsync(to, tokenId, { from: tokenOwner });
}
public async transferFromAsync(
tokenAddress: string,
@@ -114,31 +109,19 @@ export class ERC721Wrapper {
userAddress: string,
): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
await tokenContract.transferFrom.awaitTransactionSuccessAsync(
currentOwner,
userAddress,
tokenId,
{ from: currentOwner },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await tokenContract.transferFrom.awaitTransactionSuccessAsync(currentOwner, userAddress, tokenId, {
from: currentOwner,
});
}
public async mintAsync(tokenAddress: string, tokenId: BigNumber, userAddress: string): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
await tokenContract.mint.awaitTransactionSuccessAsync(
userAddress,
tokenId,
{ from: this._contractOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await tokenContract.mint.awaitTransactionSuccessAsync(userAddress, tokenId, {
from: this._contractOwnerAddress,
});
}
public async burnAsync(tokenAddress: string, tokenId: BigNumber, owner: string): Promise<void> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
await tokenContract.burn.awaitTransactionSuccessAsync(
owner,
tokenId,
{ from: this._contractOwnerAddress },
constants.AWAIT_TRANSACTION_MINED_MS,
);
await tokenContract.burn.awaitTransactionSuccessAsync(owner, tokenId, { from: this._contractOwnerAddress });
}
public async ownerOfAsync(tokenAddress: string, tokenId: BigNumber): Promise<string> {
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);

View File

@@ -0,0 +1,96 @@
/**
* Use this file to configure your truffle project. It's seeded with some
* common settings for different networks and features like migrations,
* compilation and testing. Uncomment the ones you need or modify
* them to suit your project as necessary.
*
* More information about configuration can be found at:
*
* truffleframework.com/docs/advanced/configuration
*
* To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider)
* to sign your transactions before they're sent to a remote public node. Infura accounts
* are available for free at: infura.io/register.
*
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
* public/private key pairs. If you're publishing your code to GitHub make sure you load this
* phrase from a file you've .gitignored so it doesn't accidentally become public.
*
*/
// const HDWalletProvider = require('truffle-hdwallet-provider');
// const infuraKey = "fj4jll3k.....";
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = {
/**
* Networks define how you connect to your ethereum client and let you set the
* defaults web3 uses to send transactions. If you don't specify one truffle
* will spin up a development blockchain for you on port 9545 when you
* run `develop` or `test`. You can ask a truffle command to use a specific
* network from the command line, e.g
*
* $ truffle test --network <network-name>
*/
networks: {
// Useful for testing. The `development` name is special - truffle uses it by default
// if it's defined here and no other network is specified at the command line.
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
// tab if you use this network and you must also set the `host`, `port` and `network_id`
// options below to some value.
//
// development: {
// host: "127.0.0.1", // Localhost (default: none)
// port: 8545, // Standard Ethereum port (default: none)
// network_id: "*", // Any network (default: none)
// },
// Another network with more advanced options...
// advanced: {
// port: 8777, // Custom port
// network_id: 1342, // Custom network
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
// from: <address>, // Account to send txs from (default: accounts[0])
// websockets: true // Enable EventEmitter interface for web3 (default: false)
// },
// Useful for deploying to a public network.
// NB: It's important to wrap the provider as a function.
// ropsten: {
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
// network_id: 3, // Ropsten's id
// gas: 5500000, // Ropsten has a lower block limit than mainnet
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
// },
// Useful for private networks
// private: {
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
// network_id: 2111, // This network is yours, in the cloud.
// production: true // Treats this network as if it was a public net. (default: false)
// }
},
// Set default mocha options here, use special reporters etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: '0.5.9',
settings: {
evmVersion: 'constantinople',
optimizer: {
enabled: true,
runs: 1000000,
details: { yul: true, deduplicate: true, cse: true, constantOptimizer: true },
},
},
},
},
};

View File

@@ -4,15 +4,28 @@
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": [
"generated-artifacts/ERC1155Proxy.json",
"generated-artifacts/ERC20BridgeProxy.json",
"generated-artifacts/ERC20Proxy.json",
"generated-artifacts/ERC721Proxy.json",
"generated-artifacts/Eth2DaiBridge.json",
"generated-artifacts/IAssetData.json",
"generated-artifacts/IAssetProxy.json",
"generated-artifacts/IAssetProxyDispatcher.json",
"generated-artifacts/IAuthorizable.json",
"generated-artifacts/IERC20Bridge.json",
"generated-artifacts/IEth2Dai.json",
"generated-artifacts/IUniswapExchange.json",
"generated-artifacts/IUniswapExchangeFactory.json",
"generated-artifacts/MixinAssetProxyDispatcher.json",
"generated-artifacts/MixinAuthorizable.json",
"generated-artifacts/MultiAssetProxy.json",
"generated-artifacts/Ownable.json",
"generated-artifacts/StaticCallProxy.json",
"generated-artifacts/TestStaticCallTarget.json"
"generated-artifacts/TestERC20Bridge.json",
"generated-artifacts/TestEth2DaiBridge.json",
"generated-artifacts/TestStaticCallTarget.json",
"generated-artifacts/TestUniswapBridge.json",
"generated-artifacts/UniswapBridge.json"
],
"exclude": ["./deploy/solc/solc_bin"]
}

View File

@@ -0,0 +1,2 @@
# solhint can't parse `abi.decode` syntax.
contracts/src/MixinCoordinatorApprovalVerifier.sol

View File

@@ -1,4 +1,86 @@
[
{
"version": "2.1.0-beta.1",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1573159180
},
{
"version": "2.1.0-beta.0",
"changes": [
{
"note": "Add chainId to domain separator",
"pr": 1742
},
{
"note": "Inherit Exchange domain constants from `exchange-libs` to reduce code duplication",
"pr": 1742
},
{
"note": "Update domain separator",
"pr": 1742
},
{
"note": "Refactor contract to use new ITransactions interface",
"pr": 1753
},
{
"note": "Add verifyingContractIfExists arg to LibEIP712CoordinatorDomain constructor",
"pr": 1753
},
{
"note": "Remove LibZeroExTransaction contract",
"pr": 1753
},
{
"note": "Update tests for arbitrary fee tokens (ZEIP-28).",
"pr": 1819
},
{
"note": "Update for new `marketXOrders` consolidation.",
"pr": 2042
},
{
"note": "Use built in selectors instead of hard coded constants",
"pr": 2055
},
{
"note": "Compile and export all contracts, artifacts, and wrappers by default",
"pr": 2055
}
],
"timestamp": 1570135330
},
{
"timestamp": 1568744790,
"version": "2.0.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1567521715,
"version": "2.0.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1566446343,
"version": "2.0.11",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1565296576,
"version": "2.0.10",

View File

@@ -5,6 +5,35 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.1.0-beta.1 - _November 7, 2019_
* Dependencies updated
## v2.1.0-beta.0 - _October 3, 2019_
* Add chainId to domain separator (#1742)
* Inherit Exchange domain constants from `exchange-libs` to reduce code duplication (#1742)
* Update domain separator (#1742)
* Refactor contract to use new ITransactions interface (#1753)
* Add verifyingContractIfExists arg to LibEIP712CoordinatorDomain constructor (#1753)
* Remove LibZeroExTransaction contract (#1753)
* Update tests for arbitrary fee tokens (ZEIP-28). (#1819)
* Update for new `marketXOrders` consolidation. (#2042)
* Use built in selectors instead of hard coded constants (#2055)
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
## v2.0.13 - _September 17, 2019_
* Dependencies updated
## v2.0.12 - _September 3, 2019_
* Dependencies updated
## v2.0.11 - _August 22, 2019_
* Dependencies updated
## v2.0.10 - _August 8, 2019_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
## Coordinator
This package contains a contract that allows users to call arbitrary functions on the Exchange contract with permission from one or more Coordinators. 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.
This package contains a contract that allows users to call arbitrary functions on the Exchange contract with permission from one or more Coordinators. Addresses of the deployed contracts can be found in this 0x [guide](https://0x.org/docs/guides/0x-cheat-sheet) or the [DEPLOYS](./DEPLOYS.json) file within this package.
## Installation
@@ -12,7 +12,7 @@ npm install @0x/contracts-coordinator --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).
A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0x.org/docs/guides/bug-bounty-program).
## Contributing

View File

@@ -21,6 +21,5 @@
]
}
}
},
"contracts": ["src/Coordinator.sol", "src/registry/CoordinatorRegistry.sol"]
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,10 +16,12 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol";
import "./libs/LibConstants.sol";
import "./libs/LibEIP712CoordinatorDomain.sol";
import "./MixinSignatureValidator.sol";
import "./MixinCoordinatorApprovalVerifier.sol";
import "./MixinCoordinatorCore.sol";
@@ -32,8 +34,12 @@ contract Coordinator is
MixinCoordinatorApprovalVerifier,
MixinCoordinatorCore
{
constructor (address _exchange)
/// @param exchange Address of the 0x Exchange contract.
/// @param chainId Chain ID of the network this contract is deployed on.
constructor (address exchange, uint256 chainId)
public
LibConstants(_exchange)
LibConstants(exchange)
LibEIP712CoordinatorDomain(chainId, address(0))
LibEIP712ExchangeDomain(chainId, exchange)
{}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,26 +16,28 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange-libs/contracts/src/LibExchangeSelectors.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol";
import "@0x/contracts-utils/contracts/src/LibAddressArray.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
import "./libs/LibCoordinatorApproval.sol";
import "./libs/LibZeroExTransaction.sol";
import "./mixins/MSignatureValidator.sol";
import "./mixins/MCoordinatorApprovalVerifier.sol";
import "./libs/LibCoordinatorRichErrors.sol";
import "./interfaces/ICoordinatorSignatureValidator.sol";
import "./interfaces/ICoordinatorApprovalVerifier.sol";
// solhint-disable avoid-tx-origin
contract MixinCoordinatorApprovalVerifier is
LibExchangeSelectors,
LibCoordinatorApproval,
LibZeroExTransaction,
MSignatureValidator,
MCoordinatorApprovalVerifier
LibEIP712ExchangeDomain,
ICoordinatorSignatureValidator,
ICoordinatorApprovalVerifier
{
using LibBytes for bytes;
using LibAddressArray for address[];
@@ -45,13 +47,12 @@ contract MixinCoordinatorApprovalVerifier is
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param txOrigin Required signer of Ethereum transaction calling this function.
/// @param transactionSignature Proof that the transaction has been signed by the signer.
/// @param 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 in the transaction's Exchange calldata.
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each
/// order in the transaction's Exchange calldata.
function assertValidCoordinatorApprovals(
LibZeroExTransaction.ZeroExTransaction memory transaction,
address txOrigin,
bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures
)
public
@@ -63,12 +64,11 @@ contract MixinCoordinatorApprovalVerifier is
// No approval is required for non-fill methods
if (orders.length > 0) {
// Revert if approval is invalid for transaction orders
assertValidTransactionOrdersApproval(
_assertValidTransactionOrdersApproval(
transaction,
orders,
txOrigin,
transactionSignature,
approvalExpirationTimeSeconds,
approvalSignatures
);
}
@@ -76,7 +76,7 @@ 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.
/// @return orders The orders from the Exchange calldata.
function decodeOrdersFromFillData(bytes memory data)
public
pure
@@ -84,9 +84,8 @@ contract MixinCoordinatorApprovalVerifier is
{
bytes4 selector = data.readBytes4(0);
if (
selector == FILL_ORDER_SELECTOR ||
selector == FILL_ORDER_NO_THROW_SELECTOR ||
selector == FILL_OR_KILL_ORDER_SELECTOR
selector == IExchange(address(0)).fillOrder.selector ||
selector == IExchange(address(0)).fillOrKillOrder.selector
) {
// Decode single order
(LibOrder.Order memory order) = abi.decode(
@@ -96,13 +95,13 @@ contract MixinCoordinatorApprovalVerifier is
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
selector == IExchange(address(0)).batchFillOrders.selector ||
selector == IExchange(address(0)).batchFillOrdersNoThrow.selector ||
selector == IExchange(address(0)).batchFillOrKillOrders.selector ||
selector == IExchange(address(0)).marketBuyOrdersNoThrow.selector ||
selector == IExchange(address(0)).marketBuyOrdersFillOrKill.selector ||
selector == IExchange(address(0)).marketSellOrdersNoThrow.selector ||
selector == IExchange(address(0)).marketSellOrdersFillOrKill.selector
) {
// Decode all orders
// solhint-disable indent
@@ -110,7 +109,10 @@ contract MixinCoordinatorApprovalVerifier is
data.slice(4, data.length),
(LibOrder.Order[])
);
} else if (selector == MATCH_ORDERS_SELECTOR) {
} else if (
selector == IExchange(address(0)).matchOrders.selector ||
selector == IExchange(address(0)).matchOrdersWithMaximalFill.selector
) {
// Decode left and right orders
(LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder) = abi.decode(
data.slice(4, data.length),
@@ -130,27 +132,24 @@ contract MixinCoordinatorApprovalVerifier is
/// @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(
function _assertValidTransactionOrdersApproval(
LibZeroExTransaction.ZeroExTransaction memory transaction,
LibOrder.Order[] memory orders,
address txOrigin,
bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures
)
internal
view
{
// Verify that Ethereum tx signer is the same as the approved txOrigin
require(
tx.origin == txOrigin,
"INVALID_ORIGIN"
);
if (tx.origin != txOrigin) {
LibRichErrors.rrevert(LibCoordinatorRichErrors.InvalidOriginError(txOrigin));
}
// Hash 0x transaction
bytes32 transactionHash = getTransactionHash(transaction);
bytes32 transactionHash = LibZeroExTransaction.getTypedDataHash(transaction, EIP712_EXCHANGE_DOMAIN_HASH);
// Create empty list of approval signers
address[] memory approvalSignerAddresses = new address[](0);
@@ -158,21 +157,12 @@ contract MixinCoordinatorApprovalVerifier is
uint256 signaturesLength = approvalSignatures.length;
for (uint256 i = 0; i != signaturesLength; i++) {
// Create approval message
uint256 currentApprovalExpirationTimeSeconds = approvalExpirationTimeSeconds[i];
CoordinatorApproval memory approval = CoordinatorApproval({
txOrigin: txOrigin,
transactionHash: transactionHash,
transactionSignature: transactionSignature,
approvalExpirationTimeSeconds: currentApprovalExpirationTimeSeconds
transactionSignature: transactionSignature
});
// Ensure approval has not expired
require(
// solhint-disable-next-line not-rely-on-time
currentApprovalExpirationTimeSeconds > block.timestamp,
"APPROVAL_EXPIRED"
);
// Hash approval message and recover signer address
bytes32 approvalHash = getCoordinatorApprovalHash(approval);
address approvalSignerAddress = getSignerAddress(approvalHash, approvalSignatures[i]);
@@ -194,10 +184,12 @@ contract MixinCoordinatorApprovalVerifier is
// Ensure feeRecipient of order has approved this 0x transaction
address approverAddress = orders[i].feeRecipientAddress;
bool isOrderApproved = approvalSignerAddresses.contains(approverAddress);
require(
isOrderApproved,
"INVALID_APPROVAL_SIGNATURE"
);
if (!isOrderApproved) {
LibRichErrors.rrevert(LibCoordinatorRichErrors.InvalidApprovalSignatureError(
transactionHash,
approverAddress
));
}
}
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,50 +16,57 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "./libs/LibZeroExTransaction.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol";
import "@0x/contracts-utils/contracts/src/Refundable.sol";
import "./libs/LibConstants.sol";
import "./mixins/MCoordinatorApprovalVerifier.sol";
import "./interfaces/ICoordinatorCore.sol";
import "./interfaces/ICoordinatorApprovalVerifier.sol";
// solhint-disable no-empty-blocks
contract MixinCoordinatorCore is
Refundable,
LibConstants,
MCoordinatorApprovalVerifier,
ICoordinatorApprovalVerifier,
ICoordinatorCore
{
/// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata.
/// @dev A payable fallback function that makes this contract "payable". This is necessary to allow
/// this contract to gracefully handle refunds from the Exchange.
function ()
external
payable
{}
/// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to
/// each order in the transaction's Exchange calldata.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param txOrigin Required signer of Ethereum transaction calling this function.
/// @param transactionSignature Proof that the transaction has been signed by the signer.
/// @param 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 in the transaction's Exchange calldata.
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each
/// order in the transaction's Exchange calldata.
function executeTransaction(
LibZeroExTransaction.ZeroExTransaction memory transaction,
address txOrigin,
bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures
)
public
payable
refundFinalBalance
{
// Validate that the 0x transaction has been approves by each feeRecipient
assertValidCoordinatorApprovals(
transaction,
txOrigin,
transactionSignature,
approvalExpirationTimeSeconds,
approvalSignatures
);
// Execute the transaction
EXCHANGE.executeTransaction(
transaction.salt,
transaction.signerAddress,
transaction.data,
transactionSignature
);
EXCHANGE.executeTransaction.value(msg.value)(transaction, transactionSignature);
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,38 +16,48 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "./mixins/MSignatureValidator.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "./interfaces/ICoordinatorSignatureValidator.sol";
import "./libs/LibCoordinatorRichErrors.sol";
contract MixinSignatureValidator is
MSignatureValidator
ICoordinatorSignatureValidator
{
using LibBytes for bytes;
/// @dev Recovers the address of a signer given a hash and signature.
/// @param hash Any 32 byte hash.
/// @param signature Proof that the hash has been signed by signer.
/// @return signerAddress Address of the signer.
function getSignerAddress(bytes32 hash, bytes memory signature)
public
pure
returns (address signerAddress)
{
require(
signature.length > 0,
"LENGTH_GREATER_THAN_0_REQUIRED"
);
uint256 signatureLength = signature.length;
if (signatureLength == 0) {
LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(
LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,
hash,
signature
));
}
// Pop last byte off of signature byte array.
uint8 signatureTypeRaw = uint8(signature.popLastByte());
uint8 signatureTypeRaw = uint8(signature[signature.length - 1]);
// Ensure signature is supported
require(
signatureTypeRaw < uint8(SignatureType.NSignatureTypes),
"SIGNATURE_UNSUPPORTED"
);
if (signatureTypeRaw >= uint8(SignatureType.NSignatureTypes)) {
LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(
LibCoordinatorRichErrors.SignatureErrorCodes.UNSUPPORTED,
hash,
signature
));
}
SignatureType signatureType = SignatureType(signatureTypeRaw);
@@ -57,25 +67,32 @@ contract MixinSignatureValidator is
// it an explicit option. This aids testing and analysis. It is
// also the initialization value for the enum type.
if (signatureType == SignatureType.Illegal) {
revert("SIGNATURE_ILLEGAL");
LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(
LibCoordinatorRichErrors.SignatureErrorCodes.ILLEGAL,
hash,
signature
));
// Always invalid signature.
// Like Illegal, this is always implicitly available and therefore
// offered explicitly. It can be implicitly created by providing
// a correctly formatted but incorrect signature.
} else if (signatureType == SignatureType.Invalid) {
require(
signature.length == 0,
"LENGTH_0_REQUIRED"
);
revert("SIGNATURE_INVALID");
LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(
LibCoordinatorRichErrors.SignatureErrorCodes.INVALID,
hash,
signature
));
// Signature using EIP712
} else if (signatureType == SignatureType.EIP712) {
require(
signature.length == 65,
"LENGTH_65_REQUIRED"
);
if (signatureLength != 66) {
LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(
LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,
hash,
signature
));
}
uint8 v = uint8(signature[0]);
bytes32 r = signature.readBytes32(1);
bytes32 s = signature.readBytes32(33);
@@ -89,10 +106,13 @@ contract MixinSignatureValidator is
// Signed using web3.eth_sign
} else if (signatureType == SignatureType.EthSign) {
require(
signature.length == 65,
"LENGTH_65_REQUIRED"
);
if (signatureLength != 66) {
LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(
LibCoordinatorRichErrors.SignatureErrorCodes.INVALID_LENGTH,
hash,
signature
));
}
uint8 v = uint8(signature[0]);
bytes32 r = signature.readBytes32(1);
bytes32 s = signature.readBytes32(33);
@@ -113,6 +133,10 @@ contract MixinSignatureValidator is
// that we currently support. In this case returning false
// may lead the caller to incorrectly believe that the
// signature was invalid.)
revert("SIGNATURE_UNSUPPORTED");
LibRichErrors.rrevert(LibCoordinatorRichErrors.SignatureError(
LibCoordinatorRichErrors.SignatureErrorCodes.UNSUPPORTED,
hash,
signature
));
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,11 +16,11 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "../libs/LibZeroExTransaction.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol";
contract ICoordinatorApprovalVerifier {
@@ -30,13 +30,12 @@ contract ICoordinatorApprovalVerifier {
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param txOrigin Required signer of Ethereum transaction calling this function.
/// @param transactionSignature Proof that the transaction has been signed by the signer.
/// @param 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 in the transaction's Exchange calldata.
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each
/// order in the transaction's Exchange calldata.
function assertValidCoordinatorApprovals(
LibZeroExTransaction.ZeroExTransaction memory transaction,
address txOrigin,
bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures
)
public
@@ -44,7 +43,7 @@ contract 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.
/// @return orders The orders from the Exchange calldata.
function decodeOrdersFromFillData(bytes memory data)
public
pure

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,26 +16,27 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "../libs/LibZeroExTransaction.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol";
contract ICoordinatorCore {
/// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata.
/// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to
/// each order in the transaction's Exchange calldata.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param txOrigin Required signer of Ethereum transaction calling this function.
/// @param transactionSignature Proof that the transaction has been signed by the signer.
/// @param 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 in the transaction's Exchange calldata.
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each
/// order in the transaction's Exchange calldata.
function executeTransaction(
LibZeroExTransaction.ZeroExTransaction memory transaction,
address txOrigin,
bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures
)
public;
public
payable;
}

View File

@@ -0,0 +1,45 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
contract ICoordinatorSignatureValidator {
// Allowed signature types.
enum SignatureType {
Illegal, // 0x00, default value
Invalid, // 0x01
EIP712, // 0x02
EthSign, // 0x03
Wallet, // 0x04
Validator, // 0x05
PreSigned, // 0x06
EIP1271Wallet, // 0x07
NSignatureTypes // 0x08, number of signature types. Always leave at end.
}
/// @dev Recovers the address of a signer given a hash and signature.
/// @param hash Any 32 byte hash.
/// @param signature Proof that the hash has been signed by signer.
/// @return signerAddress Address of the signer.
function getSignerAddress(bytes32 hash, bytes memory signature)
public
pure
returns (address signerAddress);
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,19 +16,21 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "../interfaces/ITransactions.sol";
import "@0x/contracts-exchange/contracts/src/interfaces/ITransactions.sol";
// solhint-disable var-name-mixedcase
contract LibConstants {
// solhint-disable-next-line var-name-mixedcase
// The 0x Exchange contract.
ITransactions internal EXCHANGE;
constructor (address _exchange)
/// @param exchange Address of the 0x Exchange contract.
constructor (address exchange)
public
{
EXCHANGE = ITransactions(_exchange);
EXCHANGE = ITransactions(exchange);
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,49 +16,52 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "./LibEIP712Domain.sol";
import "./LibEIP712CoordinatorDomain.sol";
contract LibCoordinatorApproval is
LibEIP712Domain
LibEIP712CoordinatorDomain
{
// Hash for the EIP712 Coordinator approval message
// keccak256(abi.encodePacked(
// "CoordinatorApproval(",
// "address txOrigin,",
// "bytes32 transactionHash,",
// "bytes transactionSignature,",
// "uint256 approvalExpirationTimeSeconds",
// "bytes transactionSignature",
// ")"
// ));
bytes32 constant internal EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH = 0x2fbcdbaa76bc7589916958ae919dfbef04d23f6bbf26de6ff317b32c6cc01e05;
bytes32 constant public EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH =
0xa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f8507168;
struct CoordinatorApproval {
address txOrigin; // Required signer of Ethereum transaction that is submitting approval.
bytes32 transactionHash; // EIP712 hash of the transaction.
bytes transactionSignature; // Signature of the 0x transaction.
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.
/// @dev Calculates the EIP712 hash of the Coordinator approval mesasage using the domain
/// separator of this contract.
/// @param approval Coordinator approval message containing the transaction hash, and transaction
/// signature.
/// @return approvalHash EIP712 hash of the Coordinator approval message with the domain
/// separator of this contract.
function getCoordinatorApprovalHash(CoordinatorApproval memory approval)
public
view
returns (bytes32 approvalHash)
{
approvalHash = hashEIP712CoordinatorMessage(hashCoordinatorApproval(approval));
approvalHash = _hashEIP712CoordinatorMessage(_hashCoordinatorApproval(approval));
return approvalHash;
}
/// @dev Calculated the EIP712 hash of the Coordinator approval mesasage with no domain separator.
/// @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 no domain separator.
function hashCoordinatorApproval(CoordinatorApproval memory approval)
/// @dev Calculates the EIP712 hash of the Coordinator approval mesasage with no domain separator.
/// @param approval Coordinator approval message containing the transaction hash, and transaction
// signature.
/// @return result EIP712 hash of the Coordinator approval message with no domain separator.
function _hashCoordinatorApproval(CoordinatorApproval memory approval)
internal
pure
returns (bytes32 result)
@@ -67,7 +70,6 @@ contract LibCoordinatorApproval is
bytes memory transactionSignature = approval.transactionSignature;
address txOrigin = approval.txOrigin;
bytes32 transactionHash = approval.transactionHash;
uint256 approvalExpirationTimeSeconds = approval.approvalExpirationTimeSeconds;
// Assembly for more efficiently computing:
// keccak256(abi.encodePacked(
@@ -75,7 +77,6 @@ contract LibCoordinatorApproval is
// approval.txOrigin,
// approval.transactionHash,
// keccak256(approval.transactionSignature)
// approval.approvalExpirationTimeSeconds,
// ));
assembly {
@@ -89,9 +90,8 @@ contract LibCoordinatorApproval is
mstore(add(memPtr, 32), txOrigin) // txOrigin
mstore(add(memPtr, 64), transactionHash) // transactionHash
mstore(add(memPtr, 96), transactionSignatureHash) // transactionSignatureHash
mstore(add(memPtr, 128), approvalExpirationTimeSeconds) // approvalExpirationTimeSeconds
// Compute hash
result := keccak256(memPtr, 160)
result := keccak256(memPtr, 128)
}
return result;
}

View File

@@ -0,0 +1,87 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
library LibCoordinatorRichErrors {
enum SignatureErrorCodes {
INVALID_LENGTH,
UNSUPPORTED,
ILLEGAL,
INVALID
}
// bytes4(keccak256("SignatureError(uint8,bytes32,bytes)"))
bytes4 internal constant SIGNATURE_ERROR_SELECTOR =
0x779c5223;
// bytes4(keccak256("InvalidOriginError(address)"))
bytes4 internal constant INVALID_ORIGIN_ERROR_SELECTOR =
0xa458d7ff;
// bytes4(keccak256("InvalidApprovalSignatureError(bytes32,address)"))
bytes4 internal constant INVALID_APPROVAL_SIGNATURE_ERROR_SELECTOR =
0xd789b640;
// solhint-disable func-name-mixedcase
function SignatureError(
SignatureErrorCodes errorCode,
bytes32 hash,
bytes memory signature
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
SIGNATURE_ERROR_SELECTOR,
errorCode,
hash,
signature
);
}
function InvalidOriginError(
address expectedOrigin
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
INVALID_ORIGIN_ERROR_SELECTOR,
expectedOrigin
);
}
function InvalidApprovalSignatureError(
bytes32 transactionHash,
address approverAddress
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
INVALID_APPROVAL_SIGNATURE_ERROR_SELECTOR,
transactionHash,
approverAddress
);
}
}

View File

@@ -0,0 +1,66 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibEIP712.sol";
contract LibEIP712CoordinatorDomain {
// EIP712 Domain Name value for the Coordinator
string constant public EIP712_COORDINATOR_DOMAIN_NAME = "0x Protocol Coordinator";
// EIP712 Domain Version value for the Coordinator
string constant public EIP712_COORDINATOR_DOMAIN_VERSION = "3.0.0";
// Hash of the EIP712 Domain Separator data for the Coordinator
// solhint-disable-next-line var-name-mixedcase
bytes32 public EIP712_COORDINATOR_DOMAIN_HASH;
/// @param chainId Chain ID of the network this contract is deployed on.
/// @param verifyingContractAddressIfExists Address of the verifying contract (null if the address of this contract)
constructor (
uint256 chainId,
address verifyingContractAddressIfExists
)
public
{
address verifyingContractAddress = verifyingContractAddressIfExists == address(0)
? address(this)
: verifyingContractAddressIfExists;
EIP712_COORDINATOR_DOMAIN_HASH = LibEIP712.hashEIP712Domain(
EIP712_COORDINATOR_DOMAIN_NAME,
EIP712_COORDINATOR_DOMAIN_VERSION,
chainId,
verifyingContractAddress
);
}
/// @dev Calculates EIP712 encoding for a hash struct in the EIP712 domain
/// of this contract.
/// @param hashStruct The EIP712 hash struct.
/// @return result EIP712 hash applied to this EIP712 Domain.
function _hashEIP712CoordinatorMessage(bytes32 hashStruct)
internal
view
returns (bytes32 result)
{
return LibEIP712.hashEIP712Message(EIP712_COORDINATOR_DOMAIN_HASH, hashStruct);
}
}

View File

@@ -1,131 +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;
import "./LibConstants.sol";
contract LibEIP712Domain is
LibConstants
{
// EIP191 header for EIP712 prefix
string constant internal EIP191_HEADER = "\x19\x01";
// EIP712 Domain Name value for the Coordinator
string constant internal EIP712_COORDINATOR_DOMAIN_NAME = "0x Protocol Coordinator";
// EIP712 Domain Version value for the Coordinator
string constant internal EIP712_COORDINATOR_DOMAIN_VERSION = "1.0.0";
// EIP712 Domain Name value for the Exchange
string constant internal EIP712_EXCHANGE_DOMAIN_NAME = "0x Protocol";
// EIP712 Domain Version value for the Exchange
string constant internal EIP712_EXCHANGE_DOMAIN_VERSION = "2";
// Hash of the EIP712 Domain Separator Schema
bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(
"EIP712Domain(",
"string name,",
"string version,",
"address verifyingContract",
")"
));
// Hash of the EIP712 Domain Separator data for the Coordinator
// solhint-disable-next-line var-name-mixedcase
bytes32 public EIP712_COORDINATOR_DOMAIN_HASH;
// Hash of the EIP712 Domain Separator data for the Exchange
// solhint-disable-next-line var-name-mixedcase
bytes32 public EIP712_EXCHANGE_DOMAIN_HASH;
constructor ()
public
{
EIP712_COORDINATOR_DOMAIN_HASH = keccak256(abi.encodePacked(
EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
keccak256(bytes(EIP712_COORDINATOR_DOMAIN_NAME)),
keccak256(bytes(EIP712_COORDINATOR_DOMAIN_VERSION)),
uint256(address(this))
));
EIP712_EXCHANGE_DOMAIN_HASH = keccak256(abi.encodePacked(
EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
keccak256(bytes(EIP712_EXCHANGE_DOMAIN_NAME)),
keccak256(bytes(EIP712_EXCHANGE_DOMAIN_VERSION)),
uint256(address(EXCHANGE))
));
}
/// @dev Calculates EIP712 encoding for a hash struct in the EIP712 domain
/// of this contract.
/// @param hashStruct The EIP712 hash struct.
/// @return EIP712 hash applied to this EIP712 Domain.
function hashEIP712CoordinatorMessage(bytes32 hashStruct)
internal
view
returns (bytes32 result)
{
return hashEIP712Message(EIP712_COORDINATOR_DOMAIN_HASH, hashStruct);
}
/// @dev Calculates EIP712 encoding for a hash struct in the EIP712 domain
/// of the Exchange contract.
/// @param hashStruct The EIP712 hash struct.
/// @return EIP712 hash applied to the Exchange EIP712 Domain.
function hashEIP712ExchangeMessage(bytes32 hashStruct)
internal
view
returns (bytes32 result)
{
return hashEIP712Message(EIP712_EXCHANGE_DOMAIN_HASH, hashStruct);
}
/// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.
/// @param eip712DomainHash Hash of the domain domain separator data.
/// @param hashStruct The EIP712 hash struct.
/// @return EIP712 hash applied to the Exchange EIP712 Domain.
function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)
internal
pure
returns (bytes32 result)
{
// Assembly for more efficient computing:
// keccak256(abi.encodePacked(
// EIP191_HEADER,
// EIP712_DOMAIN_HASH,
// hashStruct
// ));
assembly {
// Load free memory pointer
let memPtr := mload(64)
mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header
mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash
mstore(add(memPtr, 34), hashStruct) // Hash of struct
// Compute hash
result := keccak256(memPtr, 66)
}
return result;
}
}

View File

@@ -1,95 +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 "./LibEIP712Domain.sol";
contract LibZeroExTransaction is
LibEIP712Domain
{
// Hash for the EIP712 0x transaction schema
// keccak256(abi.encodePacked(
// "ZeroExTransaction(",
// "uint256 salt,",
// "address signerAddress,",
// "bytes data",
// ")"
// ));
bytes32 constant internal EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = 0x213c6f636f3ea94e701c0adf9b2624aa45a6c694f9a292c094f9a81c24b5df4c;
struct ZeroExTransaction {
uint256 salt; // Arbitrary number to ensure uniqueness of transaction hash.
address signerAddress; // Address of transaction signer.
bytes data; // AbiV2 encoded calldata.
}
/// @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)
public
view
returns (bytes32 transactionHash)
{
// Hash the transaction with the domain separator of the Exchange contract.
transactionHash = hashEIP712ExchangeMessage(hashZeroExTransaction(transaction));
return transactionHash;
}
/// @dev Calculates EIP712 hash of the 0x transaction with no domain separator.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @return EIP712 hash of the transaction with no domain separator.
function hashZeroExTransaction(ZeroExTransaction memory transaction)
internal
pure
returns (bytes32 result)
{
bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;
bytes memory data = transaction.data;
uint256 salt = transaction.salt;
address signerAddress = transaction.signerAddress;
// Assembly for more efficiently computing:
// keccak256(abi.encodePacked(
// EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,
// transaction.salt,
// uint256(transaction.signerAddress),
// keccak256(transaction.data)
// ));
assembly {
// Compute hash of data
let dataHash := keccak256(add(data, 32), mload(data))
// Load free memory pointer
let memPtr := mload(64)
mstore(memPtr, schemaHash) // hash of schema
mstore(add(memPtr, 32), salt) // salt
mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff)) // signerAddress
mstore(add(memPtr, 96), dataHash) // hash of data
// Compute hash
result := keccak256(memPtr, 128)
}
return result;
}
}

View File

@@ -1,46 +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 "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "../interfaces/ICoordinatorApprovalVerifier.sol";
contract MCoordinatorApprovalVerifier is
ICoordinatorApprovalVerifier
{
/// @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
view;
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,7 +16,7 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "./MixinCoordinatorRegistryCore.sol";

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,7 +16,7 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
import "./interfaces/ICoordinatorRegistryCore.sol";
@@ -29,7 +29,7 @@ contract MixinCoordinatorRegistryCore is
mapping (address => string) internal coordinatorEndpoints;
/// @dev Called by a Coordinator operator to set the endpoint of their Coordinator.
/// @param coordinatorEndpoint endpoint of the Coordinator.
/// @param coordinatorEndpoint Endpoint of the Coordinator as a string.
function setCoordinatorEndpoint(string calldata coordinatorEndpoint) external {
address coordinatorOperator = msg.sender;
coordinatorEndpoints[coordinatorOperator] = coordinatorEndpoint;
@@ -37,7 +37,8 @@ contract MixinCoordinatorRegistryCore is
}
/// @dev Gets the endpoint for a Coordinator.
/// @param coordinatorOperator operator of the Coordinator endpoint.
/// @param coordinatorOperator Operator of the Coordinator endpoint.
/// @return coordinatorEndpoint Endpoint of the Coordinator as a string.
function getCoordinatorEndpoint(address coordinatorOperator)
external
view

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -16,7 +16,7 @@
*/
pragma solidity ^0.5.5;
pragma solidity ^0.5.9;
// solhint-disable no-empty-blocks
@@ -29,11 +29,12 @@ contract ICoordinatorRegistryCore
);
/// @dev Called by a Coordinator operator to set the endpoint of their Coordinator.
/// @param coordinatorEndpoint endpoint of the Coordinator.
/// @param coordinatorEndpoint Endpoint of the Coordinator as a string.
function setCoordinatorEndpoint(string calldata coordinatorEndpoint) external;
/// @dev Gets the endpoint for a Coordinator.
/// @param coordinatorOperator operator of the Coordinator endpoint.
/// @param coordinatorOperator Operator of the Coordinator endpoint.
/// @return coordinatorEndpoint Endpoint of the Coordinator as a string.
function getCoordinatorEndpoint(address coordinatorOperator)
external
view

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-coordinator",
"version": "2.0.10",
"version": "2.1.0-beta.1",
"engines": {
"node": ">=6.12"
},
@@ -12,7 +12,7 @@
"scripts": {
"build": "yarn pre_build && tsc -b",
"build:ci": "yarn build",
"pre_build": "run-s compile generate_contract_wrappers",
"pre_build": "run-s compile contracts:gen 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",
@@ -22,7 +22,7 @@
"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",
"generate_contract_wrappers": "abi-gen --debug --abis ${npm_package_config_abis} --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
@@ -31,10 +31,11 @@
"coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test",
"contracts:gen": "contracts-gen",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
"compile:truffle": "truffle compile"
},
"config": {
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry).json",
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry|ICoordinatorApprovalVerifier|ICoordinatorCore|ICoordinatorRegistryCore|ICoordinatorSignatureValidator|LibConstants|LibCoordinatorApproval|LibCoordinatorRichErrors|LibEIP712CoordinatorDomain|MixinCoordinatorApprovalVerifier|MixinCoordinatorCore|MixinCoordinatorRegistryCore|MixinSignatureValidator).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
@@ -47,12 +48,17 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
"devDependencies": {
"@0x/abi-gen": "^4.1.0",
"@0x/contracts-gen": "^1.0.13",
"@0x/contracts-test-utils": "^3.1.13",
"@0x/dev-utils": "^2.3.0",
"@0x/sol-compiler": "^3.1.12",
"@0x/tslint-config": "^3.0.1",
"@0x/abi-gen": "^4.4.0-beta.1",
"@0x/contracts-asset-proxy": "^2.3.0-beta.1",
"@0x/contracts-dev-utils": "^0.1.0-beta.1",
"@0x/contracts-erc20": "^2.3.0-beta.1",
"@0x/contracts-exchange": "^2.2.0-beta.1",
"@0x/contracts-gen": "^1.1.0-beta.1",
"@0x/contracts-test-utils": "^3.2.0-beta.1",
"@0x/dev-utils": "^2.4.0-beta.1",
"@0x/order-utils": "^8.5.0-beta.1",
"@0x/sol-compiler": "^3.2.0-beta.1",
"@0x/tslint-config": "^3.1.0-beta.1",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "*",
@@ -60,29 +66,24 @@
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"lodash": "^4.17.11",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.3.1",
"@0x/contracts-asset-proxy": "^2.2.5",
"@0x/contracts-erc20": "^2.2.11",
"@0x/contracts-exchange": "^2.1.11",
"@0x/contracts-exchange-libs": "^3.0.5",
"@0x/contracts-utils": "^3.2.1",
"@0x/order-utils": "^8.2.5",
"@0x/types": "^2.4.1",
"@0x/typescript-typings": "^4.2.4",
"@0x/utils": "^4.5.0",
"@0x/web3-wrapper": "^6.0.10",
"ethereum-types": "^2.1.4",
"ethereumjs-util": "^5.1.1",
"lodash": "^4.17.11"
"@0x/base-contract": "^5.5.0-beta.1",
"@0x/types": "^2.5.0-beta.1",
"@0x/typescript-typings": "^4.4.0-beta.1",
"@0x/utils": "^4.6.0-beta.1",
"@0x/web3-wrapper": "^6.1.0-beta.1",
"ethereum-types": "^2.2.0-beta.1",
"ethereumjs-util": "^5.1.1"
},
"publishConfig": {
"access": "public"

View File

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

View File

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

View File

@@ -1,523 +0,0 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
artifacts as exchangeArtifacts,
ExchangeCancelEventArgs,
ExchangeCancelUpToEventArgs,
ExchangeContract,
ExchangeFillEventArgs,
} from '@0x/contracts-exchange';
import {
chaiSetup,
constants as devConstants,
expectTransactionFailedAsync,
getLatestBlockTimestampAsync,
OrderFactory,
provider,
TransactionFactory,
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
import { RevertReason, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types';
import { ApprovalFactory, artifacts, constants, CoordinatorContract, exchangeDataEncoder } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
web3Wrapper.abiDecoder.addABI(exchangeArtifacts.Exchange.compilerOutput.abi);
// tslint:disable:no-unnecessary-type-assertion
describe('Coordinator tests', () => {
let makerAddress: string;
let owner: string;
let takerAddress: string;
let feeRecipientAddress: string;
let erc20Proxy: ERC20ProxyContract;
let erc20TokenA: DummyERC20TokenContract;
let erc20TokenB: DummyERC20TokenContract;
let zrxToken: DummyERC20TokenContract;
let coordinatorContract: CoordinatorContract;
let exchange: ExchangeContract;
let erc20Wrapper: ERC20Wrapper;
let orderFactory: OrderFactory;
let takerTransactionFactory: TransactionFactory;
let makerTransactionFactory: TransactionFactory;
let approvalFactory: ApprovalFactory;
before(async () => {
await blockchainLifecycle.startAsync();
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync();
const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress] = accounts.slice(0, 4));
erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
erc20Proxy = await erc20Wrapper.deployProxyAsync();
const numDummyErc20ToDeploy = 3;
[erc20TokenA, erc20TokenB, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
numDummyErc20ToDeploy,
devConstants.DUMMY_TOKEN_DECIMALS,
);
await erc20Wrapper.setBalancesAndAllowancesAsync();
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
exchangeArtifacts.Exchange,
provider,
txDefaults,
artifacts,
assetDataUtils.encodeERC20AssetData(zrxToken.address),
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner }),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await exchange.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: owner }),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
coordinatorContract = await CoordinatorContract.deployFrom0xArtifactAsync(
artifacts.Coordinator,
provider,
txDefaults,
artifacts,
exchange.address,
);
// Configure order defaults
const defaultOrderParams = {
...devConstants.STATIC_ORDER_PARAMS,
exchangeAddress: exchange.address,
senderAddress: coordinatorContract.address,
makerAddress,
feeRecipientAddress,
makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
takerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenB.address),
};
const makerPrivateKey = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
const takerPrivateKey = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)];
const feeRecipientPrivateKey = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(feeRecipientAddress)];
orderFactory = new OrderFactory(makerPrivateKey, defaultOrderParams);
makerTransactionFactory = new TransactionFactory(makerPrivateKey, exchange.address);
takerTransactionFactory = new TransactionFactory(takerPrivateKey, exchange.address);
approvalFactory = new ApprovalFactory(feeRecipientPrivateKey, coordinatorContract.address);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
describe('single order fills', () => {
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
it(`${fnName} should fill the order with a signed approval`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: takerAddress },
),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
const fillLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
);
expect(fillLogs.length).to.eq(1);
const fillLogArgs = (fillLogs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
expect(fillLogArgs.senderAddress).to.eq(coordinatorContract.address);
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(fillLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
expect(fillLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(orders[0].makerAssetAmount);
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(orders[0].takerAssetAmount);
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(orders[0].makerFee);
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(orders[0].takerFee);
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
});
it(`${fnName} should fill the order if called by approver`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
feeRecipientAddress,
transaction.signature,
[],
[],
{ from: feeRecipientAddress },
),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
const fillLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
);
expect(fillLogs.length).to.eq(1);
const fillLogArgs = (fillLogs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
expect(fillLogArgs.senderAddress).to.eq(coordinatorContract.address);
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(fillLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
expect(fillLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(orders[0].makerAssetAmount);
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(orders[0].takerAssetAmount);
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(orders[0].makerFee);
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(orders[0].takerFee);
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
});
it(`${fnName} should revert with no approval signature`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[],
[],
{
from: takerAddress,
gas: devConstants.MAX_EXECUTE_TRANSACTION_GAS,
},
),
RevertReason.InvalidApprovalSignature,
);
});
it(`${fnName} should revert with an invalid approval signature`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[signature],
{ from: takerAddress },
),
RevertReason.InvalidApprovalSignature,
);
});
it(`${fnName} should revert with an expired approval`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: takerAddress },
),
RevertReason.ApprovalExpired,
);
});
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: owner },
),
RevertReason.InvalidOrigin,
);
});
}
});
describe('batch order fills', () => {
for (const fnName of [...constants.MARKET_FILL_FN_NAMES, ...constants.BATCH_FILL_FN_NAMES]) {
it(`${fnName} should fill the orders with a signed approval`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: takerAddress, gas: devConstants.MAX_EXECUTE_TRANSACTION_GAS },
),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
const fillLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
);
expect(fillLogs.length).to.eq(orders.length);
orders.forEach((order, index) => {
const fillLogArgs = (fillLogs[index] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
expect(fillLogArgs.senderAddress).to.eq(coordinatorContract.address);
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(fillLogArgs.makerAssetData).to.eq(order.makerAssetData);
expect(fillLogArgs.takerAssetData).to.eq(order.takerAssetData);
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(order.makerAssetAmount);
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(order.takerAssetAmount);
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(order.makerFee);
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(order.takerFee);
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
});
});
it(`${fnName} should fill the orders if called by approver`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
feeRecipientAddress,
transaction.signature,
[],
[],
{ from: feeRecipientAddress, gas: devConstants.MAX_EXECUTE_TRANSACTION_GAS },
),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
const fillLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
);
expect(fillLogs.length).to.eq(orders.length);
orders.forEach((order, index) => {
const fillLogArgs = (fillLogs[index] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
expect(fillLogArgs.senderAddress).to.eq(coordinatorContract.address);
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(fillLogArgs.makerAssetData).to.eq(order.makerAssetData);
expect(fillLogArgs.takerAssetData).to.eq(order.takerAssetData);
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(order.makerAssetAmount);
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(order.takerAssetAmount);
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(order.makerFee);
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(order.takerFee);
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
});
});
it(`${fnName} should revert with an invalid approval signature`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[signature],
{ from: takerAddress },
),
RevertReason.InvalidApprovalSignature,
);
});
it(`${fnName} should revert with an expired approval`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: takerAddress },
),
RevertReason.ApprovalExpired,
);
});
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
takerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: owner },
),
RevertReason.InvalidOrigin,
);
});
}
});
describe('cancels', () => {
it('cancelOrder call should be successful without an approval', async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDER, orders);
const transaction = makerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
makerAddress,
transaction.signature,
[],
[],
{
from: makerAddress,
},
),
);
const cancelLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeCancelEventArgs>).event === 'Cancel',
);
expect(cancelLogs.length).to.eq(1);
const cancelLogArgs = (cancelLogs[0] as LogWithDecodedArgs<ExchangeCancelEventArgs>).args;
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
expect(cancelLogArgs.senderAddress).to.eq(coordinatorContract.address);
expect(cancelLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(cancelLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
expect(cancelLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
expect(cancelLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
});
it('batchCancelOrders call should be successful without an approval', async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.BATCH_CANCEL_ORDERS, orders);
const transaction = makerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
makerAddress,
transaction.signature,
[],
[],
{
from: makerAddress,
},
),
);
const cancelLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeCancelEventArgs>).event === 'Cancel',
);
expect(cancelLogs.length).to.eq(orders.length);
orders.forEach((order, index) => {
const cancelLogArgs = (cancelLogs[index] as LogWithDecodedArgs<ExchangeCancelEventArgs>).args;
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
expect(cancelLogArgs.senderAddress).to.eq(coordinatorContract.address);
expect(cancelLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(cancelLogArgs.makerAssetData).to.eq(order.makerAssetData);
expect(cancelLogArgs.takerAssetData).to.eq(order.takerAssetData);
expect(cancelLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
});
});
it('cancelOrdersUpTo call should be successful without an approval', async () => {
const orders: SignedOrder[] = [];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS_UP_TO, orders);
const transaction = makerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction,
makerAddress,
transaction.signature,
[],
[],
{
from: makerAddress,
},
),
);
const cancelLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeCancelUpToEventArgs>).event === 'CancelUpTo',
);
expect(cancelLogs.length).to.eq(1);
const cancelLogArgs = (cancelLogs[0] as LogWithDecodedArgs<ExchangeCancelUpToEventArgs>).args;
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
expect(cancelLogArgs.senderAddress).to.eq(coordinatorContract.address);
expect(cancelLogArgs.orderEpoch).to.bignumber.eq(new BigNumber(1));
});
});
});
// tslint:disable:max-file-line-count

View File

@@ -1,81 +1,72 @@
import { artifacts as exchangeArtifacts } from '@0x/contracts-exchange';
import { chaiSetup, provider, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types';
import { blockchainTests, expect, verifyEvents } from '@0x/contracts-test-utils';
import { CoordinatorRegistryCoordinatorEndpointSetEventArgs } from '../src';
import { artifacts, CoordinatorRegistryContract, CoordinatorRegistryCoordinatorEndpointSetEventArgs } from '../src';
import { CoordinatorRegistryWrapper } from './utils/coordinator_registry_wrapper';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
web3Wrapper.abiDecoder.addABI(exchangeArtifacts.Exchange.compilerOutput.abi);
// tslint:disable:no-unnecessary-type-assertion
describe('Coordinator Registry tests', () => {
blockchainTests.resets('Coordinator Registry tests', env => {
let coordinatorRegistry: CoordinatorRegistryContract;
let coordinatorOperator: string;
const coordinatorEndpoint = 'http://sometec.0x.org';
const nilCoordinatorEndpoint = '';
let coordinatorRegistryWrapper: CoordinatorRegistryWrapper;
// tests
before(async () => {
await blockchainLifecycle.startAsync();
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
// setup accounts (skip owner)
const accounts = await web3Wrapper.getAvailableAddressesAsync();
const accounts = await env.getAccountAddressesAsync();
[, coordinatorOperator] = accounts;
// deploy coordinator registry
coordinatorRegistryWrapper = new CoordinatorRegistryWrapper(provider);
await coordinatorRegistryWrapper.deployCoordinatorRegistryAsync();
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
coordinatorRegistry = await CoordinatorRegistryContract.deployFrom0xArtifactAsync(
artifacts.CoordinatorRegistry,
env.provider,
env.txDefaults,
artifacts,
);
});
describe('core', () => {
it('Should successfully set a Coordinator endpoint', async () => {
await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(coordinatorOperator, coordinatorEndpoint);
const recordedCoordinatorEndpoint = await coordinatorRegistryWrapper.getCoordinatorEndpointAsync(
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, {
from: coordinatorOperator,
});
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
});
it('Should successfully unset a Coordinator endpoint', async () => {
// set Coordinator endpoint
await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(coordinatorOperator, coordinatorEndpoint);
let recordedCoordinatorEndpoint = await coordinatorRegistryWrapper.getCoordinatorEndpointAsync(
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, {
from: coordinatorOperator,
});
let recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
// unset Coordinator endpoint
await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(coordinatorOperator, nilCoordinatorEndpoint);
recordedCoordinatorEndpoint = await coordinatorRegistryWrapper.getCoordinatorEndpointAsync(
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(nilCoordinatorEndpoint, {
from: coordinatorOperator,
});
recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
expect(recordedCoordinatorEndpoint).to.be.equal(nilCoordinatorEndpoint);
});
it('Should emit an event when setting Coordinator endpoint', async () => {
// set Coordinator endpoint
const txReceipt = await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(
coordinatorOperator,
const txReceipt = await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(
coordinatorEndpoint,
{
from: coordinatorOperator,
},
);
const recordedCoordinatorEndpoint = await coordinatorRegistryWrapper.getCoordinatorEndpointAsync(
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
// validate event
expect(txReceipt.logs.length).to.be.equal(1);
const log = txReceipt.logs[0] as LogWithDecodedArgs<CoordinatorRegistryCoordinatorEndpointSetEventArgs>;
expect(log.args.coordinatorOperator).to.be.equal(coordinatorOperator);
expect(log.args.coordinatorEndpoint).to.be.equal(coordinatorEndpoint);
const expectedEvent: CoordinatorRegistryCoordinatorEndpointSetEventArgs = {
coordinatorOperator,
coordinatorEndpoint,
};
verifyEvents(txReceipt, [expectedEvent], 'CoordinatorEndpointSet');
});
});
});

View File

@@ -1,78 +1,47 @@
import { addressUtils, chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { blockchainTests, constants, expect, randomAddress } from '@0x/contracts-test-utils';
import { transactionHashUtils } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import { artifacts, CoordinatorContract, hashUtils } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('Libs tests', () => {
blockchainTests.resets('Libs tests', env => {
let coordinatorContract: CoordinatorContract;
const exchangeAddress = addressUtils.generatePseudoRandomAddress();
let chainId: number;
const exchangeAddress = randomAddress();
before(async () => {
await blockchainLifecycle.startAsync();
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
chainId = await env.getChainIdAsync();
coordinatorContract = await CoordinatorContract.deployFrom0xArtifactAsync(
artifacts.Coordinator,
provider,
txDefaults,
env.provider,
env.txDefaults,
artifacts,
exchangeAddress,
new BigNumber(chainId),
);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
describe('getTransactionHash', () => {
it('should return the correct transaction hash', async () => {
const tx = {
verifyingContractAddress: exchangeAddress,
salt: new BigNumber(0),
signerAddress: constants.NULL_ADDRESS,
data: '0x1234',
};
const expectedTxHash = transactionHashUtils.getTransactionHashHex(tx);
const txHash = await coordinatorContract.getTransactionHash.callAsync(tx);
expect(expectedTxHash).to.eq(txHash);
});
});
describe('getApprovalHash', () => {
it('should return the correct approval hash', async () => {
const signedTx = {
verifyingContractAddress: exchangeAddress,
salt: new BigNumber(0),
salt: constants.ZERO_AMOUNT,
gasPrice: constants.ZERO_AMOUNT,
expirationTimeSeconds: constants.ZERO_AMOUNT,
signerAddress: constants.NULL_ADDRESS,
data: '0x1234',
signature: '0x5678',
domain: {
verifyingContract: exchangeAddress,
chainId,
},
};
const approvalExpirationTimeSeconds = new BigNumber(0);
const txOrigin = constants.NULL_ADDRESS;
const approval = {
txOrigin,
transactionHash: transactionHashUtils.getTransactionHashHex(signedTx),
transactionSignature: signedTx.signature,
approvalExpirationTimeSeconds,
};
const expectedApprovalHash = hashUtils.getApprovalHashHex(
signedTx,
coordinatorContract.address,
txOrigin,
approvalExpirationTimeSeconds,
);
const expectedApprovalHash = hashUtils.getApprovalHashHex(signedTx, coordinatorContract.address, txOrigin);
const approvalHash = await coordinatorContract.getCoordinatorApprovalHash.callAsync(approval);
expect(expectedApprovalHash).to.eq(approvalHash);
});

View File

@@ -1,28 +1,21 @@
import { constants as exchangeConstants, exchangeDataEncoder, ExchangeFunctionName } from '@0x/contracts-exchange';
import {
addressUtils,
chaiSetup,
constants as devConstants,
expectContractCallFailedAsync,
getLatestBlockTimestampAsync,
provider,
blockchainTests,
constants,
expect,
hexConcat,
hexSlice,
randomAddress,
TransactionFactory,
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { transactionHashUtils } from '@0x/order-utils';
import { RevertReason, SignatureType, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as ethUtil from 'ethereumjs-util';
import { CoordinatorRevertErrors, transactionHashUtils } from '@0x/order-utils';
import { SignatureType, SignedOrder } from '@0x/types';
import { BigNumber, LibBytesRevertErrors } from '@0x/utils';
import { ApprovalFactory, artifacts, constants, CoordinatorContract, exchangeDataEncoder } from '../src';
import { ApprovalFactory, artifacts, CoordinatorContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('Mixins tests', () => {
blockchainTests.resets('Mixins tests', env => {
let chainId: number;
let transactionSignerAddress: string;
let approvalSignerAddress1: string;
let approvalSignerAddress2: string;
@@ -31,152 +24,183 @@ describe('Mixins tests', () => {
let approvalFactory1: ApprovalFactory;
let approvalFactory2: ApprovalFactory;
let defaultOrder: SignedOrder;
const exchangeAddress = addressUtils.generatePseudoRandomAddress();
const exchangeAddress = randomAddress();
before(async () => {
await blockchainLifecycle.startAsync();
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
chainId = await env.getChainIdAsync();
mixins = await CoordinatorContract.deployFrom0xArtifactAsync(
artifacts.Coordinator,
provider,
txDefaults,
env.provider,
env.txDefaults,
artifacts,
exchangeAddress,
new BigNumber(chainId),
);
const accounts = await web3Wrapper.getAvailableAddressesAsync();
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts.slice(0, 3);
const accounts = await env.getAccountAddressesAsync();
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts;
defaultOrder = {
exchangeAddress: devConstants.NULL_ADDRESS,
makerAddress: devConstants.NULL_ADDRESS,
takerAddress: devConstants.NULL_ADDRESS,
makerAddress: constants.NULL_ADDRESS,
takerAddress: constants.NULL_ADDRESS,
senderAddress: mixins.address,
feeRecipientAddress: approvalSignerAddress1,
makerAssetData: devConstants.NULL_BYTES,
takerAssetData: devConstants.NULL_BYTES,
makerAssetAmount: devConstants.ZERO_AMOUNT,
takerAssetAmount: devConstants.ZERO_AMOUNT,
makerFee: devConstants.ZERO_AMOUNT,
takerFee: devConstants.ZERO_AMOUNT,
expirationTimeSeconds: devConstants.ZERO_AMOUNT,
salt: devConstants.ZERO_AMOUNT,
signature: devConstants.NULL_BYTES,
makerAssetData: constants.NULL_BYTES,
takerAssetData: constants.NULL_BYTES,
makerAssetAmount: constants.ZERO_AMOUNT,
takerAssetAmount: constants.ZERO_AMOUNT,
makerFee: constants.ZERO_AMOUNT,
takerFee: constants.ZERO_AMOUNT,
makerFeeAssetData: constants.NULL_BYTES,
takerFeeAssetData: constants.NULL_BYTES,
expirationTimeSeconds: constants.ZERO_AMOUNT,
salt: constants.ZERO_AMOUNT,
signature: constants.NULL_BYTES,
exchangeAddress: constants.NULL_ADDRESS,
chainId,
};
const transactionSignerPrivateKey =
devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(transactionSignerAddress)];
const approvalSignerPrivateKey1 = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(approvalSignerAddress1)];
const approvalSignerPrivateKey2 = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(approvalSignerAddress2)];
transactionFactory = new TransactionFactory(transactionSignerPrivateKey, exchangeAddress);
const transactionSignerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(transactionSignerAddress)];
const approvalSignerPrivateKey1 = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(approvalSignerAddress1)];
const approvalSignerPrivateKey2 = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(approvalSignerAddress2)];
transactionFactory = new TransactionFactory(transactionSignerPrivateKey, exchangeAddress, chainId);
approvalFactory1 = new ApprovalFactory(approvalSignerPrivateKey1, mixins.address);
approvalFactory2 = new ApprovalFactory(approvalSignerPrivateKey2, mixins.address);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
describe('getSignerAddress', () => {
it('should return the correct address using the EthSign signature type', async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedTransaction(data, SignatureType.EthSign);
const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EthSign);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature);
expect(transaction.signerAddress).to.eq(signerAddress);
});
it('should return the correct address using the EIP712 signature type', async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedTransaction(data, SignatureType.EIP712);
const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data }, SignatureType.EIP712);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature);
expect(transaction.signerAddress).to.eq(signerAddress);
});
it('should revert with with the Illegal signature type', async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedTransaction(data);
const illegalSignatureByte = ethUtil.toBuffer(SignatureType.Illegal).toString('hex');
transaction.signature = `${transaction.signature.slice(
0,
transaction.signature.length - 2,
)}${illegalSignatureByte}`;
const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat(
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
SignatureType.Illegal,
);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expectContractCallFailedAsync(
mixins.getSignerAddress.callAsync(transactionHash, transaction.signature),
RevertReason.SignatureIllegal,
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
new CoordinatorRevertErrors.SignatureError(
CoordinatorRevertErrors.SignatureErrorCodes.Illegal,
transactionHash,
transaction.signature,
),
);
});
it('should revert with with the Invalid signature type', async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedTransaction(data);
const invalidSignatureByte = ethUtil.toBuffer(SignatureType.Invalid).toString('hex');
transaction.signature = `0x${invalidSignatureByte}`;
const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat(SignatureType.Invalid);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expectContractCallFailedAsync(
mixins.getSignerAddress.callAsync(transactionHash, transaction.signature),
RevertReason.SignatureInvalid,
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
new CoordinatorRevertErrors.SignatureError(
CoordinatorRevertErrors.SignatureErrorCodes.Invalid,
transactionHash,
transaction.signature,
),
);
});
it("should revert with with a signature type that doesn't exist", async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedTransaction(data);
const invalidSignatureByte = '04';
transaction.signature = `${transaction.signature.slice(
0,
transaction.signature.length - 2,
)}${invalidSignatureByte}`;
it('should revert with with a signature type that equals `NSignatureTypes`', async () => {
const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat(
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
SignatureType.NSignatureTypes,
);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expectContractCallFailedAsync(
mixins.getSignerAddress.callAsync(transactionHash, transaction.signature),
RevertReason.SignatureUnsupported,
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
new CoordinatorRevertErrors.SignatureError(
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
transactionHash,
transaction.signature,
),
);
});
it("should revert with with a signature type that isn't supported", async () => {
const data = constants.NULL_BYTES;
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
transaction.signature = hexConcat(
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
SignatureType.Wallet,
);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
new CoordinatorRevertErrors.SignatureError(
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
transactionHash,
transaction.signature,
),
);
});
});
describe('decodeOrdersFromFillData', () => {
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
for (const fnName of exchangeConstants.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,
signature: constants.NULL_BYTES,
exchangeAddress: constants.NULL_ADDRESS,
chainId,
}));
expect(orders).to.deep.eq(decodedSignedOrders);
});
}
for (const fnName of constants.BATCH_FILL_FN_NAMES) {
for (const fnName of exchangeConstants.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,
signature: constants.NULL_BYTES,
exchangeAddress: constants.NULL_ADDRESS,
chainId,
}));
expect(orders).to.deep.eq(decodedSignedOrders);
});
}
for (const fnName of constants.MARKET_FILL_FN_NAMES) {
for (const fnName of exchangeConstants.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,
signature: constants.NULL_BYTES,
exchangeAddress: constants.NULL_ADDRESS,
chainId,
}));
expect(orders).to.deep.eq(decodedSignedOrders);
});
}
for (const fnName of [constants.CANCEL_ORDER, constants.BATCH_CANCEL_ORDERS, constants.CANCEL_ORDERS_UP_TO]) {
for (const fnName of exchangeConstants.MATCH_ORDER_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
const decodedSignedOrders = decodedOrders.map(order => ({
...order,
signature: constants.NULL_BYTES,
exchangeAddress: constants.NULL_ADDRESS,
chainId,
}));
expect(orders).to.deep.eq(decodedSignedOrders);
});
}
for (const fnName of exchangeConstants.CANCEL_ORDER_FN_NAMES) {
it(`should correctly decode the orders for ${fnName} data`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
@@ -193,534 +217,369 @@ describe('Mixins tests', () => {
});
it('should revert if data is less than 4 bytes long', async () => {
const data = '0x010203';
await expectContractCallFailedAsync(
mixins.decodeOrdersFromFillData.callAsync(data),
RevertReason.LibBytesGreaterOrEqualTo4LengthRequired,
const expectedError = new LibBytesRevertErrors.InvalidByteOperationError(
LibBytesRevertErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsFourRequired,
new BigNumber(3), // the length of data
new BigNumber(4),
);
return expect(mixins.decodeOrdersFromFillData.callAsync(data)).to.revertWith(expectedError);
});
});
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 () => {
for (const fnName of exchangeConstants.SINGLE_FILL_FN_NAMES) {
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1], expiration=[valid]`, async () => {
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1]`, async () => {
const order = {
...defaultOrder,
senderAddress: devConstants.NULL_ADDRESS,
senderAddress: constants.NULL_ADDRESS,
};
const orders = [order];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => {
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[],
[],
{
from: approvalSignerAddress1,
},
);
});
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: approvalSignerAddress1 },
);
});
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => {
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[],
[],
{
from: approvalSignerAddress1,
},
);
});
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid], expiration=[valid]`, async () => {
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const signature = hexConcat(
hexSlice(approval.signature, 0, 2),
'0xFFFFFFFF',
hexSlice(approval.signature, 6),
);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
transaction.signature,
[signature],
{ from: transactionSignerAddress },
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[signature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith(
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
);
});
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
);
});
it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidOrigin,
transaction.signature,
[approval.signature],
{ from: approvalSignerAddress2 },
);
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
});
}
});
describe('Batch order approvals', () => {
for (const fnName of [
...constants.BATCH_FILL_FN_NAMES,
...constants.MARKET_FILL_FN_NAMES,
constants.MATCH_ORDERS,
...exchangeConstants.BATCH_FILL_FN_NAMES,
...exchangeConstants.MARKET_FILL_FN_NAMES,
...exchangeConstants.MATCH_ORDER_FN_NAMES,
]) {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder, defaultOrder].map(order => ({
...order,
senderAddress: devConstants.NULL_ADDRESS,
senderAddress: constants.NULL_ADDRESS,
}));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
const orders = [defaultOrder, defaultOrder].map(order => ({
...order,
senderAddress: devConstants.NULL_ADDRESS,
senderAddress: constants.NULL_ADDRESS,
}));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, senderAddress: devConstants.NULL_ADDRESS }];
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, senderAddress: constants.NULL_ADDRESS }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2], expiration=[valid,valid]`, async () => {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[],
[],
{ from: approvalSignerAddress1 },
);
});
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2], expiration=[valid]`, async () => {
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.signature],
{ from: approvalSignerAddress1 },
),
RevertReason.InvalidOrigin,
transaction.signature,
[approval2.signature],
{ from: approvalSignerAddress1 },
);
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
});
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[], expiration=[]`, async () => {
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
{ from: transactionSignerAddress },
);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith(
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
);
});
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid], expiration=[valid]`, async () => {
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const signature = hexConcat(
hexSlice(approval.signature, 0, 2),
'0xFFFFFFFF',
hexSlice(approval.signature, 6),
);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
transaction.signature,
[signature],
{ from: transactionSignerAddress },
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[signature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith(
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
);
});
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid], expiration=[valid,valid]`, async () => {
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
const approvalSignature2 = hexConcat(
hexSlice(approval2.signature, 0, 2),
'0xFFFFFFFF',
hexSlice(approval2.signature, 6),
);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
transaction.signature,
[approval1.signature, approvalSignature2],
{ from: transactionSignerAddress },
);
const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.signature, approvalSignature2],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith(
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress2),
);
});
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid], expiration=[valid]`, async () => {
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
const approvalSignature2 = hexConcat(
hexSlice(approval2.signature, 0, 2),
'0xFFFFFFFF',
hexSlice(approval2.signature, 6),
);
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature2],
{ from: approvalSignerAddress1 },
),
RevertReason.InvalidApprovalSignature,
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[approvalSignature2],
{ from: approvalSignerAddress1 },
);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expect(tx).to.revertWith(
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress2),
);
});
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,valid], expiration=[valid,invalid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds1,
);
const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds2,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
);
});
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid], expiration=[invalid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.signature],
{ from: approvalSignerAddress1 },
),
RevertReason.ApprovalExpired,
);
});
it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid], expiration=[valid]`, async () => {
it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval1.signature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidOrigin,
transaction.signature,
[approval1.signature],
{ from: approvalSignerAddress2 },
);
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
});
}
});
describe('cancels', () => {
it('should allow the tx signer to call `cancelOrder` without approval', async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDER, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
});
it('should allow the tx signer to call `batchCancelOrders` without approval', async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.BATCH_CANCEL_ORDERS, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.BatchCancelOrders, orders);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
});
it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => {
const orders: SignedOrder[] = [];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS_UP_TO, orders);
const transaction = transactionFactory.newSignedTransaction(data);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo);
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
});

View File

@@ -1,7 +1,5 @@
import { signingUtils } from '@0x/contracts-test-utils';
import { hexConcat, signingUtils } from '@0x/contracts-test-utils';
import { SignatureType, SignedZeroExTransaction } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as ethUtil from 'ethereumjs-util';
import { hashUtils, SignedCoordinatorApproval } from './index';
@@ -9,29 +7,22 @@ export class ApprovalFactory {
private readonly _privateKey: Buffer;
private readonly _verifyingContractAddress: string;
constructor(privateKey: Buffer, verifyingContractAddress: string) {
constructor(privateKey: Buffer, verifyingContract: string) {
this._privateKey = privateKey;
this._verifyingContractAddress = verifyingContractAddress;
this._verifyingContractAddress = verifyingContract;
}
public newSignedApproval(
transaction: SignedZeroExTransaction,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
signatureType: SignatureType = SignatureType.EthSign,
): SignedCoordinatorApproval {
const approvalHashBuff = hashUtils.getApprovalHashBuffer(
transaction,
this._verifyingContractAddress,
txOrigin,
approvalExpirationTimeSeconds,
);
const approvalHashBuff = hashUtils.getApprovalHashBuffer(transaction, this._verifyingContractAddress, txOrigin);
const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType);
const signedApproval = {
txOrigin,
transaction,
approvalExpirationTimeSeconds,
signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')),
signature: hexConcat(signatureBuff),
};
return signedApproval;
}

View File

@@ -1,12 +0,0 @@
import { BigNumber } from '@0x/utils';
export const constants = {
SINGLE_FILL_FN_NAMES: ['fillOrder', 'fillOrKillOrder', 'fillOrderNoThrow'],
BATCH_FILL_FN_NAMES: ['batchFillOrders', 'batchFillOrKillOrders', 'batchFillOrdersNoThrow'],
MARKET_FILL_FN_NAMES: ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow'],
MATCH_ORDERS: 'matchOrders',
CANCEL_ORDER: 'cancelOrder',
BATCH_CANCEL_ORDERS: 'batchCancelOrders',
CANCEL_ORDERS_UP_TO: 'cancelOrdersUpTo',
TIME_BUFFER: new BigNumber(1000),
};

View File

@@ -1,65 +0,0 @@
import { LogDecoder, txDefaults } from '@0x/contracts-test-utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import { TransactionReceiptWithDecodedLogs, ZeroExProvider } from 'ethereum-types';
import { artifacts, CoordinatorRegistryContract } from '../../src';
export class CoordinatorRegistryWrapper {
private readonly _web3Wrapper: Web3Wrapper;
private readonly _provider: ZeroExProvider;
private readonly _logDecoder: LogDecoder;
private _coordinatorRegistryContract?: CoordinatorRegistryContract;
/**
* Instanitates an CoordinatorRegistryWrapper
* @param provider Web3 provider to use for all JSON RPC requests
* Instance of CoordinatorRegistryWrapper
*/
constructor(provider: ZeroExProvider) {
this._web3Wrapper = new Web3Wrapper(provider);
this._provider = provider;
this._logDecoder = new LogDecoder(this._web3Wrapper, artifacts);
}
public async deployCoordinatorRegistryAsync(): Promise<CoordinatorRegistryContract> {
this._coordinatorRegistryContract = await CoordinatorRegistryContract.deployFrom0xArtifactAsync(
artifacts.CoordinatorRegistry,
this._provider,
txDefaults,
artifacts,
);
if (this._coordinatorRegistryContract === undefined) {
throw new Error(`Failed to deploy Coordinator Registry contract.`);
}
return this._coordinatorRegistryContract;
}
public async setCoordinatorEndpointAsync(
coordinatorOperator: string,
coordinatorEndpoint: string,
): Promise<TransactionReceiptWithDecodedLogs> {
this._assertCoordinatorRegistryDeployed();
const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(
await (this
._coordinatorRegistryContract as CoordinatorRegistryContract).setCoordinatorEndpoint.sendTransactionAsync(
coordinatorEndpoint,
{
from: coordinatorOperator,
},
),
);
return txReceipt;
}
public async getCoordinatorEndpointAsync(coordinatorOperator: string): Promise<string> {
this._assertCoordinatorRegistryDeployed();
const coordinatorEndpoint = await (this
._coordinatorRegistryContract as CoordinatorRegistryContract).getCoordinatorEndpoint.callAsync(
coordinatorOperator,
);
return coordinatorEndpoint;
}
private _assertCoordinatorRegistryDeployed(): void {
if (this._coordinatorRegistryContract === undefined) {
throw new Error(
'The Coordinator Registry contract was not deployed through the CoordinatorRegistryWrapper. Call `deployCoordinatorRegistryAsync` to deploy.',
);
}
}
}

View File

@@ -1,47 +0,0 @@
import { IExchangeContract } from '@0x/contracts-exchange';
import { constants as devConstants, provider } from '@0x/contracts-test-utils';
import { SignedOrder } from '@0x/types';
import { constants } from './index';
export const exchangeDataEncoder = {
encodeOrdersToExchangeData(fnName: string, orders: SignedOrder[]): string {
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(
orders[0],
orders[0].takerAssetAmount,
orders[0].signature,
);
} else if (constants.BATCH_FILL_FN_NAMES.indexOf(fnName) !== -1) {
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
orders,
orders.map(order => order.takerAssetAmount),
orders.map(order => order.signature),
);
} else if (constants.MARKET_FILL_FN_NAMES.indexOf(fnName) !== -1) {
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
orders,
orders.map(order => order.takerAssetAmount).reduce((prev, curr) => prev.plus(curr)),
orders.map(order => order.signature),
);
} else if (fnName === constants.MATCH_ORDERS) {
data = exchangeInstance.matchOrders.getABIEncodedTransactionData(
orders[0],
orders[1],
orders[0].signature,
orders[1].signature,
);
} else if (fnName === constants.CANCEL_ORDER) {
data = exchangeInstance.cancelOrder.getABIEncodedTransactionData(orders[0]);
} else if (fnName === constants.BATCH_CANCEL_ORDERS) {
data = exchangeInstance.batchCancelOrders.getABIEncodedTransactionData(orders);
} else if (fnName === constants.CANCEL_ORDERS_UP_TO) {
data = exchangeInstance.cancelOrdersUpTo.getABIEncodedTransactionData(devConstants.ZERO_AMOUNT);
} else {
throw new Error(`Error: ${fnName} not a supported function`);
}
return data;
},
};

View File

@@ -1,33 +1,16 @@
import { hexConcat } from '@0x/contracts-test-utils';
import { eip712Utils } from '@0x/order-utils';
import { SignedZeroExTransaction } from '@0x/types';
import { BigNumber, signTypedDataUtils } from '@0x/utils';
import * as _ from 'lodash';
import { signTypedDataUtils } from '@0x/utils';
export const hashUtils = {
getApprovalHashBuffer(
transaction: SignedZeroExTransaction,
verifyingContractAddress: string,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
): Buffer {
const typedData = eip712Utils.createCoordinatorApprovalTypedData(
transaction,
verifyingContractAddress,
txOrigin,
approvalExpirationTimeSeconds,
);
getApprovalHashBuffer(transaction: SignedZeroExTransaction, verifyingContract: string, txOrigin: string): Buffer {
const typedData = eip712Utils.createCoordinatorApprovalTypedData(transaction, verifyingContract, txOrigin);
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
return hashBuffer;
},
getApprovalHashHex(
transaction: SignedZeroExTransaction,
verifyingContractAddress: string,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
): string {
const hashHex = `0x${hashUtils
.getApprovalHashBuffer(transaction, verifyingContractAddress, txOrigin, approvalExpirationTimeSeconds)
.toString('hex')}`;
getApprovalHashHex(transaction: SignedZeroExTransaction, verifyingContract: string, txOrigin: string): string {
const hashHex = hexConcat(hashUtils.getApprovalHashBuffer(transaction, verifyingContract, txOrigin));
return hashHex;
},
};

View File

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

View File

@@ -1,10 +1,8 @@
import { SignedZeroExTransaction } from '@0x/types';
import { BigNumber } from '@0x/utils';
export interface CoordinatorApproval {
transaction: SignedZeroExTransaction;
txOrigin: string;
approvalExpirationTimeSeconds: BigNumber;
}
export interface SignedCoordinatorApproval extends CoordinatorApproval {

View File

@@ -0,0 +1,96 @@
/**
* Use this file to configure your truffle project. It's seeded with some
* common settings for different networks and features like migrations,
* compilation and testing. Uncomment the ones you need or modify
* them to suit your project as necessary.
*
* More information about configuration can be found at:
*
* truffleframework.com/docs/advanced/configuration
*
* To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider)
* to sign your transactions before they're sent to a remote public node. Infura accounts
* are available for free at: infura.io/register.
*
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
* public/private key pairs. If you're publishing your code to GitHub make sure you load this
* phrase from a file you've .gitignored so it doesn't accidentally become public.
*
*/
// const HDWalletProvider = require('truffle-hdwallet-provider');
// const infuraKey = "fj4jll3k.....";
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = {
/**
* Networks define how you connect to your ethereum client and let you set the
* defaults web3 uses to send transactions. If you don't specify one truffle
* will spin up a development blockchain for you on port 9545 when you
* run `develop` or `test`. You can ask a truffle command to use a specific
* network from the command line, e.g
*
* $ truffle test --network <network-name>
*/
networks: {
// Useful for testing. The `development` name is special - truffle uses it by default
// if it's defined here and no other network is specified at the command line.
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
// tab if you use this network and you must also set the `host`, `port` and `network_id`
// options below to some value.
//
// development: {
// host: "127.0.0.1", // Localhost (default: none)
// port: 8545, // Standard Ethereum port (default: none)
// network_id: "*", // Any network (default: none)
// },
// Another network with more advanced options...
// advanced: {
// port: 8777, // Custom port
// network_id: 1342, // Custom network
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
// from: <address>, // Account to send txs from (default: accounts[0])
// websockets: true // Enable EventEmitter interface for web3 (default: false)
// },
// Useful for deploying to a public network.
// NB: It's important to wrap the provider as a function.
// ropsten: {
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
// network_id: 3, // Ropsten's id
// gas: 5500000, // Ropsten has a lower block limit than mainnet
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
// },
// Useful for private networks
// private: {
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
// network_id: 2111, // This network is yours, in the cloud.
// production: true // Treats this network as if it was a public net. (default: false)
// }
},
// Set default mocha options here, use special reporters etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: '0.5.9',
settings: {
evmVersion: 'constantinople',
optimizer: {
enabled: true,
runs: 1000000,
details: { yul: true, deduplicate: true, cse: true, constantOptimizer: true },
},
},
},
},
};

View File

@@ -2,6 +2,21 @@
"extends": "../../tsconfig",
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": ["generated-artifacts/Coordinator.json", "generated-artifacts/CoordinatorRegistry.json"],
"files": [
"generated-artifacts/Coordinator.json",
"generated-artifacts/CoordinatorRegistry.json",
"generated-artifacts/ICoordinatorApprovalVerifier.json",
"generated-artifacts/ICoordinatorCore.json",
"generated-artifacts/ICoordinatorRegistryCore.json",
"generated-artifacts/ICoordinatorSignatureValidator.json",
"generated-artifacts/LibConstants.json",
"generated-artifacts/LibCoordinatorApproval.json",
"generated-artifacts/LibCoordinatorRichErrors.json",
"generated-artifacts/LibEIP712CoordinatorDomain.json",
"generated-artifacts/MixinCoordinatorApprovalVerifier.json",
"generated-artifacts/MixinCoordinatorCore.json",
"generated-artifacts/MixinCoordinatorRegistryCore.json",
"generated-artifacts/MixinSignatureValidator.json"
],
"exclude": ["./deploy/solc/solc_bin"]
}

View File

@@ -1,4 +1,67 @@
[
{
"version": "0.1.0-beta.1",
"changes": [
{
"note": "Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData",
"pr": 2034
},
{
"note": "Add `revertIfInvalidAssetData` in LibAssetData",
"pr": 2034
}
],
"timestamp": 1573159180
},
{
"version": "0.1.0-beta.0",
"changes": [
{
"note": "Use built in selectors instead of hard coded constants",
"pr": 2055
},
{
"note": "Compile and export all contracts, artifacts, and wrappers by default",
"pr": 2055
},
{
"note": "Add `marketBuy/SellOrdersNoThrow` and `marketBuy/SellOrdersFillOrKill` to `LibTransactionDecoder`.",
"pr": 2075
},
{
"note": "`run_mocha` package script runs with `UNLIMITED_CONTRACT_SIZE=true` environment variable.",
"pr": 2075
}
],
"timestamp": 1570135330
},
{
"timestamp": 1568744790,
"version": "0.0.10",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1567521715,
"version": "0.0.9",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1566446343,
"version": "0.0.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1565296576,
"version": "0.0.7",
@@ -89,6 +152,14 @@
{
"note": "Add support for StaticCallProxy",
"pr": 1863
},
{
"note": "Add `OrderTransferSimulationUtils` contract for simulating order transfers on-chain",
"pr": 1868
},
{
"note": "Updated to use the new rich error pattern from @0x/contracts-exchange",
"pr": 1913
}
]
}

View File

@@ -5,6 +5,30 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.1.0-beta.1 - _November 7, 2019_
* Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData (#2034)
* Add `revertIfInvalidAssetData` in LibAssetData (#2034)
## v0.1.0-beta.0 - _October 3, 2019_
* Use built in selectors instead of hard coded constants (#2055)
* Compile and export all contracts, artifacts, and wrappers by default (#2055)
* Add `marketBuy/SellOrdersNoThrow` and `marketBuy/SellOrdersFillOrKill` to `LibTransactionDecoder`. (#2075)
* `run_mocha` package script runs with `UNLIMITED_CONTRACT_SIZE=true` environment variable. (#2075)
## v0.0.10 - _September 17, 2019_
* Dependencies updated
## v0.0.9 - _September 3, 2019_
* Dependencies updated
## v0.0.8 - _August 22, 2019_
* Dependencies updated
## v0.0.7 - _August 8, 2019_
* Dependencies updated
@@ -41,3 +65,5 @@ CHANGELOG
* Refactor `LibAssetData` balance/allowance checks to never revert (#1848)
* Refactor `OrderValidationUtils` to calculate `fillableTakerAssetAmount` (#1848)
* Add support for StaticCallProxy (#1863)
* Add `OrderTransferSimulationUtils` contract for simulating order transfers on-chain (#1868)
* Updated to use the new rich error pattern from @0x/contracts-exchange (#1913)

View File

@@ -1,6 +1,6 @@
## 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.
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 this 0x [guide](https://0x.org/docs/guides/0x-cheat-sheet) or the [DEPLOYS](./DEPLOYS.json) file within this package.
## Installation
@@ -12,7 +12,7 @@ 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).
A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0x.org/docs/guides/bug-bounty-program).
## Contributing

View File

@@ -7,7 +7,7 @@
"evmVersion": "constantinople",
"optimizer": {
"enabled": true,
"runs": 1000000,
"runs": 10000,
"details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
},
"outputSelection": {
@@ -22,11 +22,5 @@
]
}
}
},
"contracts": [
"src/DevUtils.sol",
"src/LibAssetData.sol",
"src/LibTransactionDecoder.sol",
"src/EthBalanceChecker.sol"
]
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
@@ -20,6 +20,7 @@ pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "./OrderValidationUtils.sol";
import "./OrderTransferSimulationUtils.sol";
import "./LibTransactionDecoder.sol";
import "./EthBalanceChecker.sol";
@@ -28,10 +29,12 @@ import "./EthBalanceChecker.sol";
contract DevUtils is
OrderValidationUtils,
LibTransactionDecoder,
EthBalanceChecker
EthBalanceChecker,
OrderTransferSimulationUtils
{
constructor (address _exchange, bytes memory _zrxAssetData)
constructor (address _exchange)
public
OrderValidationUtils(_exchange, _zrxAssetData)
OrderValidationUtils(_exchange)
OrderTransferSimulationUtils(_exchange)
{}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.

View File

@@ -20,32 +20,19 @@ 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";
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetData.sol";
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetProxy.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-erc721/contracts/src/interfaces/IERC721Token.sol";
import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol";
contract LibAssetData is
LibAssetProxyIds
{
contract LibAssetData {
// 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
@@ -60,10 +47,10 @@ contract LibAssetData is
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);
_ERC20_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(IAssetData(address(0)).ERC20Token.selector);
_ERC721_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(IAssetData(address(0)).ERC721Token.selector);
_ERC1155_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(IAssetData(address(0)).ERC1155Assets.selector);
_STATIC_CALL_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(IAssetData(address(0)).StaticCall.selector);
}
/// @dev Returns the owner's balance of the assets(s) specified in
@@ -81,23 +68,33 @@ contract LibAssetData is
// Get id of AssetProxy contract
bytes4 assetProxyId = assetData.readBytes4(0);
if (assetProxyId == ERC20_PROXY_ID) {
if (assetProxyId == IAssetData(address(0)).ERC20Token.selector) {
// Get ERC20 token address
address tokenAddress = assetData.readAddress(16);
// Encode data for `balanceOf(ownerAddress)`
bytes memory balanceOfData = abi.encodeWithSelector(_ERC20_BALANCE_OF_SELECTOR, ownerAddress);
bytes memory balanceOfData = abi.encodeWithSelector(
IERC20Token(address(0)).balanceOf.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) {
} else if (assetProxyId == IAssetData(address(0)).ERC721Token.selector) {
// 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) {
bytes memory ownerOfCalldata = abi.encodeWithSelector(
IERC721Token(address(0)).ownerOf.selector,
tokenId
);
(bool success, bytes memory returnData) = tokenAddress.staticcall(ownerOfCalldata);
address currentOwnerAddress = (success && returnData.length == 32) ? returnData.readAddress(12) : address(0);
balance = currentOwnerAddress == ownerAddress ? 1 : 0;
} else if (assetProxyId == IAssetData(address(0)).ERC1155Assets.selector) {
// Get ERC1155 token address, array of ids, and array of values
(, address tokenAddress, uint256[] memory tokenIds, uint256[] memory tokenValues,) = decodeERC1155AssetData(assetData);
@@ -105,7 +102,7 @@ contract LibAssetData is
for (uint256 i = 0; i != length; i++) {
// Encode data for `balanceOf(ownerAddress, tokenIds[i])
bytes memory balanceOfData = abi.encodeWithSelector(
_ERC1155_BALANCE_OF_SELECTOR,
IERC1155(address(0)).balanceOf.selector,
ownerAddress,
tokenIds[i]
);
@@ -120,10 +117,10 @@ contract LibAssetData is
balance = scaledBalance;
}
}
} else if (assetProxyId == STATIC_CALL_PROXY_ID) {
} else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) {
// Encode data for `staticCallProxy.transferFrom(assetData,...)`
bytes memory transferFromData = abi.encodeWithSelector(
_ASSET_PROXY_TRANSFER_FROM_SELECTOR,
IAssetProxy(address(0)).transferFrom.selector,
assetData,
address(0), // `from` address is not used
address(0), // `to` address is not used
@@ -135,7 +132,7 @@ contract LibAssetData is
// 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) {
} else if (assetProxyId == IAssetData(address(0)).MultiAsset.selector) {
// Get array of values and array of assetDatas
(, uint256[] memory assetAmounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData);
@@ -190,7 +187,7 @@ contract LibAssetData is
// Get id of AssetProxy contract
bytes4 assetProxyId = assetData.readBytes4(0);
if (assetProxyId == MULTI_ASSET_PROXY_ID) {
if (assetProxyId == IAssetData(address(0)).MultiAsset.selector) {
// Get array of values and array of assetDatas
(, uint256[] memory amounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData);
@@ -208,13 +205,13 @@ contract LibAssetData is
return allowance;
}
if (assetProxyId == ERC20_PROXY_ID) {
if (assetProxyId == IAssetData(address(0)).ERC20Token.selector) {
// 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,
IERC20Token(address(0)).allowance.selector,
ownerAddress,
_ERC20_PROXY_ADDRESS
);
@@ -222,13 +219,13 @@ contract LibAssetData is
// 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) {
} else if (assetProxyId == IAssetData(address(0)).ERC721Token.selector) {
// 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,
IERC721Token(address(0)).isApprovedForAll.selector,
ownerAddress,
_ERC721_PROXY_ADDRESS
);
@@ -238,7 +235,7 @@ contract LibAssetData is
// 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);
bytes memory getApprovedData = abi.encodeWithSelector(IERC721Token(address(0)).getApproved.selector, tokenId);
(success, returnData) = tokenAddress.staticcall(getApprovedData);
// Allowance is 1 if successful and the approved address is the ERC721Proxy
@@ -247,13 +244,13 @@ contract LibAssetData is
// Allowance is 2^256 - 1 if `isApprovedForAll` returned true
allowance = _MAX_UINT256;
}
} else if (assetProxyId == ERC1155_PROXY_ID) {
} else if (assetProxyId == IAssetData(address(0)).ERC1155Assets.selector) {
// 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,
IERC1155(address(0)).isApprovedForAll.selector,
ownerAddress,
_ERC1155_PROXY_ADDRESS
);
@@ -261,7 +258,7 @@ contract LibAssetData is
// 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) {
} else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) {
// The StaticCallProxy does not require any approvals
allowance = _MAX_UINT256;
}
@@ -319,6 +316,29 @@ contract LibAssetData is
return (balances, allowances);
}
/// @dev Decode AssetProxy identifier
/// @param assetData AssetProxy-compliant asset data describing an ERC-20, ERC-721, ERC1155, or MultiAsset asset.
/// @return The AssetProxy identifier
function decodeAssetProxyId(bytes memory assetData)
public
pure
returns (
bytes4 assetProxyId
)
{
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == IAssetData(address(0)).ERC20Token.selector ||
assetProxyId == IAssetData(address(0)).ERC721Token.selector ||
assetProxyId == IAssetData(address(0)).ERC1155Assets.selector ||
assetProxyId == IAssetData(address(0)).MultiAsset.selector ||
assetProxyId == IAssetData(address(0)).StaticCall.selector,
"WRONG_PROXY_ID"
);
return assetProxyId;
}
/// @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.
@@ -327,13 +347,13 @@ contract LibAssetData is
pure
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(ERC20_PROXY_ID, tokenAddress);
assetData = abi.encodeWithSelector(IAssetData(address(0)).ERC20Token.selector, 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
/// @return The AssetProxy identifier, and the address of the ERC-20
/// contract hosting this asset.
function decodeERC20AssetData(bytes memory assetData)
public
@@ -346,7 +366,7 @@ contract LibAssetData is
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC20_PROXY_ID,
assetProxyId == IAssetData(address(0)).ERC20Token.selector,
"WRONG_PROXY_ID"
);
@@ -364,7 +384,7 @@ contract LibAssetData is
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
ERC721_PROXY_ID,
IAssetData(address(0)).ERC721Token.selector,
tokenAddress,
tokenId
);
@@ -388,7 +408,7 @@ contract LibAssetData is
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC721_PROXY_ID,
assetProxyId == IAssetData(address(0)).ERC721Token.selector,
"WRONG_PROXY_ID"
);
@@ -414,7 +434,7 @@ contract LibAssetData is
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
ERC1155_PROXY_ID,
IAssetData(address(0)).ERC1155Assets.selector,
tokenAddress,
tokenIds,
tokenValues,
@@ -446,7 +466,7 @@ contract LibAssetData is
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC1155_PROXY_ID,
assetProxyId == IAssetData(address(0)).ERC1155Assets.selector,
"WRONG_PROXY_ID"
);
@@ -482,7 +502,7 @@ contract LibAssetData is
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
MULTI_ASSET_PROXY_ID,
IAssetData(address(0)).MultiAsset.selector,
amounts,
nestedAssetData
);
@@ -507,7 +527,7 @@ contract LibAssetData is
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == MULTI_ASSET_PROXY_ID,
assetProxyId == IAssetData(address(0)).MultiAsset.selector,
"WRONG_PROXY_ID"
);
@@ -519,23 +539,74 @@ contract LibAssetData is
// 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)
/// @dev Encode StaticCall asset data into the format described in the AssetProxy contract specification.
/// @param staticCallTargetAddress Target address of StaticCall.
/// @param staticCallData Data that will be passed to staticCallTargetAddress in the StaticCall.
/// @param expectedReturnDataHash Expected Keccak-256 hash of the StaticCall return data.
/// @return AssetProxy-compliant asset data describing the set of assets.
function encodeStaticCallAssetData(
address staticCallTargetAddress,
bytes memory staticCallData,
bytes32 expectedReturnDataHash
)
public
view
returns (address ownerAddress)
pure
returns (bytes memory assetData)
{
bytes memory ownerOfCalldata = abi.encodeWithSelector(
_ERC721_OWNER_OF_SELECTOR,
tokenId
assetData = abi.encodeWithSelector(
IAssetData(address(0)).StaticCall.selector,
staticCallTargetAddress,
staticCallData,
expectedReturnDataHash
);
return assetData;
}
/// @dev Decode StaticCall asset data from the format described in the AssetProxy contract specification.
/// @param assetData AssetProxy-compliant asset data describing a StaticCall asset
/// @return The StaticCall AssetProxy identifier, the target address of the StaticCAll, the data to be
/// passed to the target address, and the expected Keccak-256 hash of the static call return data.
function decodeStaticCallAssetData(bytes memory assetData)
public
pure
returns (
bytes4 assetProxyId,
address staticCallTargetAddress,
bytes memory staticCallData,
bytes32 expectedReturnDataHash
)
{
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == IAssetData(address(0)).StaticCall.selector,
"WRONG_PROXY_ID"
);
(bool success, bytes memory returnData) = tokenAddress.staticcall(ownerOfCalldata);
(staticCallTargetAddress, staticCallData, expectedReturnDataHash) = abi.decode(
assetData.slice(4, assetData.length),
(address, bytes, bytes32)
);
}
ownerAddress = (success && returnData.length == 32) ? returnData.readAddress(12) : address(0);
return ownerAddress;
function revertIfInvalidAssetData(bytes memory assetData)
public
pure
{
bytes4 assetProxyId = assetData.readBytes4(0);
if (assetProxyId == IAssetData(address(0)).ERC20Token.selector) {
decodeERC20AssetData(assetData);
} else if (assetProxyId == IAssetData(address(0)).ERC721Token.selector) {
decodeERC721AssetData(assetData);
} else if (assetProxyId == IAssetData(address(0)).ERC1155Assets.selector) {
decodeERC1155AssetData(assetData);
} else if (assetProxyId == IAssetData(address(0)).MultiAsset.selector) {
decodeMultiAssetData(assetData);
} else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) {
decodeStaticCallAssetData(assetData);
} else {
revert("WRONG_PROXY_ID");
}
}
}

View File

@@ -19,14 +19,13 @@
pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange-libs/contracts/src/LibExchangeSelectors.sol";
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
contract LibTransactionDecoder is
LibExchangeSelectors
{
contract LibTransactionDecoder {
using LibBytes for bytes;
/// @dev Decodes the call data for an Exchange contract method call.
@@ -47,72 +46,68 @@ contract LibTransactionDecoder is
{
bytes4 functionSelector = transactionData.readBytes4(0);
if (functionSelector == BATCH_CANCEL_ORDERS_SELECTOR) {
if (functionSelector == IExchange(address(0)).batchCancelOrders.selector) {
functionName = "batchCancelOrders";
} else if (functionSelector == BATCH_FILL_ORDERS_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).batchFillOrders.selector) {
functionName = "batchFillOrders";
} else if (functionSelector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).batchFillOrdersNoThrow.selector) {
functionName = "batchFillOrdersNoThrow";
} else if (functionSelector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).batchFillOrKillOrders.selector) {
functionName = "batchFillOrKillOrders";
} else if (functionSelector == CANCEL_ORDER_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).cancelOrder.selector) {
functionName = "cancelOrder";
} else if (functionSelector == FILL_ORDER_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).fillOrder.selector) {
functionName = "fillOrder";
} else if (functionSelector == FILL_ORDER_NO_THROW_SELECTOR) {
functionName = "fillOrderNoThrow";
} else if (functionSelector == FILL_OR_KILL_ORDER_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).fillOrKillOrder.selector) {
functionName = "fillOrKillOrder";
} else if (functionSelector == MARKET_BUY_ORDERS_SELECTOR) {
functionName = "marketBuyOrders";
} else if (functionSelector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).marketBuyOrdersNoThrow.selector) {
functionName = "marketBuyOrdersNoThrow";
} else if (functionSelector == MARKET_SELL_ORDERS_SELECTOR) {
functionName = "marketSellOrders";
} else if (functionSelector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).marketSellOrdersNoThrow.selector) {
functionName = "marketSellOrdersNoThrow";
} else if (functionSelector == MATCH_ORDERS_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).marketBuyOrdersFillOrKill.selector) {
functionName = "marketBuyOrdersFillOrKill";
} else if (functionSelector == IExchange(address(0)).marketSellOrdersFillOrKill.selector) {
functionName = "marketSellOrdersFillOrKill";
} else if (functionSelector == IExchange(address(0)).matchOrders.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.
functionSelector == IExchange(address(0)).cancelOrdersUpTo.selector ||
functionSelector == IExchange(address(0)).executeTransaction.selector
) {
revert("UNIMPLEMENTED");
} else {
revert("UNKNOWN_FUNCTION_SELECTOR");
}
if (functionSelector == BATCH_CANCEL_ORDERS_SELECTOR) {
if (functionSelector == IExchange(address(0)).batchCancelOrders.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
functionSelector == IExchange(address(0)).batchFillOrKillOrders.selector ||
functionSelector == IExchange(address(0)).batchFillOrders.selector ||
functionSelector == IExchange(address(0)).batchFillOrdersNoThrow.selector
) {
(orders, takerAssetFillAmounts, signatures) = _makeReturnValuesForBatchFill(transactionData);
} else if (functionSelector == CANCEL_ORDER_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).cancelOrder.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
functionSelector == IExchange(address(0)).fillOrKillOrder.selector ||
functionSelector == IExchange(address(0)).fillOrder.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
functionSelector == IExchange(address(0)).marketBuyOrdersNoThrow.selector ||
functionSelector == IExchange(address(0)).marketSellOrdersNoThrow.selector ||
functionSelector == IExchange(address(0)).marketBuyOrdersFillOrKill.selector ||
functionSelector == IExchange(address(0)).marketSellOrdersFillOrKill.selector
) {
(orders, takerAssetFillAmounts, signatures) = _makeReturnValuesForMarketFill(transactionData);
} else if (functionSelector == MATCH_ORDERS_SELECTOR) {
} else if (functionSelector == IExchange(address(0)).matchOrders.selector) {
(
LibOrder.Order memory leftOrder,
LibOrder.Order memory rightOrder,

View File

@@ -0,0 +1,160 @@
/*
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/contracts/src/interfaces/IExchange.sol";
import "@0x/contracts-exchange/contracts/src/libs/LibExchangeRichErrorDecoder.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibExchangeRichErrors.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
contract OrderTransferSimulationUtils is
LibExchangeRichErrorDecoder
{
using LibBytes for bytes;
enum OrderTransferResults {
TakerAssetDataFailed, // Transfer of takerAsset failed
MakerAssetDataFailed, // Transfer of makerAsset failed
TakerFeeAssetDataFailed, // Transfer of takerFeeAsset failed
MakerFeeAssetDataFailed, // Transfer of makerFeeAsset failed
TransfersSuccessful // All transfers in the order were successful
}
// keccak256(abi.encodeWithSignature("Error(string)", "TRANSFERS_SUCCESSFUL"));
bytes32 constant internal _TRANSFERS_SUCCESSFUL_RESULT_HASH = 0xf43f26ea5a94b478394a975e856464913dc1a8a1ca70939d974aa7c238aa0ce0;
// solhint-disable var-name-mixedcase
IExchange internal _EXCHANGE;
// solhint-enable var-name-mixedcase
constructor (address _exchange)
public
{
_EXCHANGE = IExchange(_exchange);
}
/// @dev Simulates all of the transfers within an order and returns the index of the first failed transfer.
/// @param order The order to simulate transfers for.
/// @param takerAddress The address of the taker that will fill the order.
/// @param takerAssetFillAmount The amount of takerAsset that the taker wished to fill.
/// @return The index of the first failed transfer (or 4 if all transfers are successful).
function getSimulatedOrderTransferResults(
LibOrder.Order memory order,
address takerAddress,
uint256 takerAssetFillAmount
)
public
returns (OrderTransferResults orderTransferResults)
{
LibFillResults.FillResults memory fillResults = LibFillResults.calculateFillResults(
order,
takerAssetFillAmount,
_EXCHANGE.protocolFeeMultiplier(),
tx.gasprice
);
// Create input arrays
bytes[] memory assetData = new bytes[](4);
address[] memory fromAddresses = new address[](4);
address[] memory toAddresses = new address[](4);
uint256[] memory amounts = new uint256[](4);
// Transfer `takerAsset` from taker to maker
assetData[0] = order.takerAssetData;
fromAddresses[0] = takerAddress;
toAddresses[0] = order.makerAddress;
amounts[0] = takerAssetFillAmount;
// Transfer `makerAsset` from maker to taker
assetData[1] = order.makerAssetData;
fromAddresses[1] = order.makerAddress;
toAddresses[1] = takerAddress;
amounts[1] = fillResults.makerAssetFilledAmount;
// Transfer `takerFeeAsset` from taker to feeRecipient
assetData[2] = order.takerFeeAssetData;
fromAddresses[2] = takerAddress;
toAddresses[2] = order.feeRecipientAddress;
amounts[2] = fillResults.takerFeePaid;
// Transfer `makerFeeAsset` from maker to feeRecipient
assetData[3] = order.makerFeeAssetData;
fromAddresses[3] = order.makerAddress;
toAddresses[3] = order.feeRecipientAddress;
amounts[3] = fillResults.makerFeePaid;
// Encode data for `simulateDispatchTransferFromCalls(assetData, fromAddresses, toAddresses, amounts)`
bytes memory simulateDispatchTransferFromCallsData = abi.encodeWithSelector(
IExchange(address(0)).simulateDispatchTransferFromCalls.selector,
assetData,
fromAddresses,
toAddresses,
amounts
);
// Perform call and catch revert
(, bytes memory returnData) = address(_EXCHANGE).call(simulateDispatchTransferFromCallsData);
bytes4 selector = returnData.readBytes4(0);
if (selector == LibExchangeRichErrors.AssetProxyDispatchErrorSelector()) {
// Decode AssetProxyDispatchError and return index of failed transfer
(, bytes32 failedTransferIndex,) = decodeAssetProxyDispatchError(returnData);
return OrderTransferResults(uint8(uint256(failedTransferIndex)));
} else if (selector == LibExchangeRichErrors.AssetProxyTransferErrorSelector()) {
// Decode AssetProxyTransferError and return index of failed transfer
(bytes32 failedTransferIndex, ,) = decodeAssetProxyTransferError(returnData);
return OrderTransferResults(uint8(uint256(failedTransferIndex)));
} else if (keccak256(returnData) == _TRANSFERS_SUCCESSFUL_RESULT_HASH) {
// All transfers were successful
return OrderTransferResults.TransfersSuccessful;
} else {
revert("UNKNOWN_RETURN_DATA");
}
}
/// @dev Simulates all of the transfers for each given order and returns the indices of each first failed transfer.
/// @param orders Array of orders to individually simulate transfers for.
/// @param takerAddresses Array of addresses of takers that will fill each order.
/// @param takerAssetFillAmounts Array of amounts of takerAsset that will be filled for each order.
/// @return The indices of the first failed transfer (or 4 if all transfers are successful) for each order.
function getSimulatedOrdersTransferResults(
LibOrder.Order[] memory orders,
address[] memory takerAddresses,
uint256[] memory takerAssetFillAmounts
)
public
returns (OrderTransferResults[] memory orderTransferResults)
{
uint256 length = orders.length;
orderTransferResults = new OrderTransferResults[](length);
for (uint256 i = 0; i != length; i++) {
orderTransferResults[i] = getSimulatedOrderTransferResults(
orders[i],
takerAddresses[i],
takerAssetFillAmounts[i]
);
}
return orderTransferResults;
}
}

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