Compare commits

..

68 Commits

Author SHA1 Message Date
Fabio Berger
599554b785 Publish
- 0x.js@0.38.5
 - @0xproject/abi-gen@0.3.3
 - @0xproject/assert@0.2.13
 - @0xproject/base-contract@0.3.5
 - @0xproject/connect@0.6.16
 - @0xproject/contract-wrappers@0.1.0
 - contracts@2.1.34
 - @0xproject/dev-utils@0.4.5
 - @0xproject/fill-scenarios@0.0.5
 - @0xproject/json-schemas@0.8.2
 - @0xproject/metacoin@0.0.9
 - @0xproject/migrations@0.0.9
 - @0xproject/monorepo-scripts@0.2.2
 - @0xproject/order-utils@0.0.8
 - @0xproject/order-watcher@0.0.7
 - @0xproject/react-docs-example@0.0.14
 - @0xproject/react-docs@0.0.15
 - @0xproject/react-shared@0.2.2
 - @0xproject/sol-compiler@0.5.3
 - @0xproject/sol-cov@0.1.2
 - @0xproject/sol-resolver@0.0.8
 - @0xproject/sra-report@0.1.5
 - @0xproject/subproviders@0.10.5
 - @0xproject/testnet-faucets@1.0.35
 - @0xproject/tslint-config@0.4.21
 - @0xproject/types@0.8.2
 - @0xproject/typescript-typings@0.4.2
 - @0xproject/utils@0.7.2
 - @0xproject/web3-wrapper@0.7.2
 - @0xproject/website@0.0.38
2018-07-09 17:24:22 +02:00
Fabio Berger
d57d282cab Updated CHANGELOGS 2018-07-09 17:24:12 +02:00
Fabio Berger
562bef98e2 reset dep cache 2018-07-09 16:57:40 +02:00
Fabio Berger
900f819be8 Use node v9 everywhere 2018-07-09 16:54:34 +02:00
Fabio Berger
e7337c2451 Update yarn.lock 2018-07-09 16:30:46 +02:00
Fabio Berger
dc81193132 Update package so works with node v9 2018-07-09 16:22:46 +02:00
Fabio Berger
fa868b4963 Bump up node version to v9 2018-07-09 16:09:31 +02:00
Fabio Berger
62945ad363 Updated contract-wrappers to use blockstream v5 and stop unsubscribing on blocksteam error 2018-07-09 15:35:08 +02:00
Fabio Berger
61c38d35be Update yarn.lock 2018-07-09 14:14:03 +02:00
Fabio Berger
4e0ec72896 Merge branch 'development' of github.com:0xProject/0x-monorepo into development
* 'development' of github.com:0xProject/0x-monorepo:
  Add missing import
  Extend from DecodedLogArgs and fix type names
  Update ethers typings & changelog
  Back-port order-watcher changes from v2-prototype
  Back-port over utils changes from v2-prototype
2018-07-09 14:10:29 +02:00
Fabio Berger
c28289e9a8 Back-port prePublish fixes 2018-07-09 14:05:29 +02:00
Fabio Berger
e7e9ddf232 remove excess new line 2018-07-09 14:03:17 +02:00
Fabio Berger
f03784ba37 update web3-provider-engine in subproviders 2018-07-09 14:01:47 +02:00
Fabio Berger
2445e23c0b Merge pull request #842 from 0xProject/back-port-v2-prototype
Back-port changes from v2-prototype in order to publish working Order-watcher
2018-07-09 13:53:15 +02:00
Fabio Berger
cd29483187 merge development 2018-07-09 13:52:21 +02:00
Fabio Berger
9bacbdab48 Add missing import 2018-07-09 13:47:33 +02:00
Fabio Berger
551d484fb7 Extend from DecodedLogArgs and fix type names 2018-07-09 13:03:53 +02:00
Fabio Berger
ff66432b83 Update ethers typings & changelog 2018-07-09 12:33:44 +02:00
Fabio Berger
a7ae82a2d1 Back-port order-watcher changes from v2-prototype 2018-07-09 12:31:06 +02:00
Fabio Berger
5f34b5a80e Back-port over utils changes from v2-prototype 2018-07-09 11:48:30 +02:00
Leonid Logvinov
8fca2a8116 Merge pull request #768 from galkin/development
Improve 'web3-provider-engine' typings
2018-06-27 09:24:33 +03:00
Nikita Galkin
5472500119 Improve 'web3-provider-engine' typings 2018-06-25 12:22:54 +03:00
Fabio Berger
8fb5c29b4b Publish
- 0x.js@0.38.4
 - @0xproject/abi-gen@0.3.2
 - @0xproject/assert@0.2.12
 - @0xproject/base-contract@0.3.4
 - @0xproject/connect@0.6.15
 - @0xproject/contract-wrappers@0.0.5
 - contracts@2.1.33
 - @0xproject/dev-utils@0.4.4
 - @0xproject/fill-scenarios@0.0.4
 - @0xproject/json-schemas@0.8.1
 - @0xproject/metacoin@0.0.8
 - @0xproject/migrations@0.0.8
 - @0xproject/monorepo-scripts@0.2.1
 - @0xproject/order-utils@0.0.7
 - @0xproject/order-watcher@0.0.6
 - @0xproject/react-docs-example@0.0.13
 - @0xproject/react-docs@0.0.14
 - @0xproject/react-shared@0.2.1
 - @0xproject/sol-compiler@0.5.2
 - @0xproject/sol-cov@0.1.1
 - @0xproject/sol-resolver@0.0.7
 - @0xproject/sra-report@0.1.4
 - @0xproject/subproviders@0.10.4
 - @0xproject/testnet-faucets@1.0.34
 - @0xproject/tslint-config@0.4.20
 - @0xproject/types@0.8.1
 - @0xproject/typescript-typings@0.4.1
 - @0xproject/utils@0.7.1
 - @0xproject/web3-wrapper@0.7.1
 - @0xproject/website@0.0.37
2018-06-19 10:48:07 +02:00
Fabio Berger
40a061a5ca Updated CHANGELOGS 2018-06-19 10:48:00 +02:00
Fabio Berger
2ef82592a3 Improve error message 2018-06-19 10:36:19 +02:00
Fabio Berger
14b5448d70 Add missing timestamp 2018-06-19 10:35:22 +02:00
Fabio Berger
e7d45e47bf Remove the hotfix for Ethersjs and instead update to the fixed version in all packages 2018-06-19 10:30:49 +02:00
Fabio Berger
28268d4355 Update versions and CHANGELOG's to account for unpublished versions on NPM 2018-06-18 23:18:42 +02:00
Fabio Berger
50fa02c1d1 Small fixes 2018-06-18 23:16:44 +02:00
Fabio Berger
b36ff9103d Merge pull request #718 from 0xProject/improvement/publishing-flow
Improve Pre-publishing flow
2018-06-18 23:01:36 +02:00
Fabio Berger
f032c2466c Use semver package instead of getNextPatchVersion 2018-06-18 19:22:31 +02:00
Fabio Berger
b63ddc9be4 Use semver external librarty instead of semverUtils 2018-06-18 19:00:39 +02:00
Fabio Berger
171430b617 small fixes 2018-06-18 17:58:17 +02:00
Fabio Berger
d561043774 Show all errors of a given kind at once rather then throwing after the first instance is encountered 2018-06-18 17:41:03 +02:00
Fabio Berger
b1871e9ddd fix package.json 2018-06-18 16:57:22 +02:00
Fabio Berger
b4a5e7258c Add the following prePublish checks:
- That package version matches latest NPM package version (including unpublished versions)
- That changelogs are properly formatted (lastEntry version >= currentVersion, no accidental timestamps)
- Checks for and removes any git tags locally and remotely that might be left-over from a previous failed publish

Moved changelog related helpers to changelogUtils and other small cleanup refactors.
2018-06-18 16:55:59 +02:00
Fabio Berger
3c75debdf9 Remove the remove_tags script 2018-06-18 16:46:54 +02:00
Fabio Berger
84d1053f73 Add missing timestamp to web3-wrapper changelog 2018-06-15 17:11:30 +02:00
Fabio Berger
f9df42f5d9 Fix incorrect merges 2018-06-15 16:58:36 +02:00
Leonid Logvinov
4414ef0a0f fix cherry-pick 2018-06-15 16:51:13 +02:00
Leonid Logvinov
b7729ada38 fix cherry-pick 2018-06-15 16:48:29 +02:00
Leonid Logvinov
3da67feeb2 Add prepublish_checks 2018-06-15 16:45:18 +02:00
Leonid Logvinov
8a0d563a32 Add CHANGELOG entry 2018-06-15 16:44:48 +02:00
Leonid Logvinov
612fc4a949 Fix cherry-pick 2018-06-15 16:44:35 +02:00
Fabio Berger
bf915ce403 Merge pull request #709 from 0xProject/feature/pin-deps
[DEVELOPMENT] Ethersjs Issue Hot Fix
2018-06-15 14:14:45 +02:00
Fabio Berger
0f9ea9773e Add lib/test and ganache.log to npmignore 2018-06-15 14:14:30 +02:00
Fabio Berger
447a3a6c26 Fix prettier 2018-06-15 13:53:26 +02:00
Fabio Berger
f1cc16c44d Export OrderWatcherConfig from 0x.js 2018-06-15 13:38:25 +02:00
Fabio Berger
aae16b6343 Add ganache.log to gitignore 2018-06-15 13:37:08 +02:00
Fabio Berger
834e1538d1 Fix typos, versions and other mistypings 2018-06-15 11:48:52 +02:00
Leonid Logvinov
afc489bc2c Pin all external dependencies 2018-06-14 21:25:36 -07:00
Leonid Logvinov
3e061e7364 Fix the is not a function bug caused by breaking patch version https://github.com/ethers-io/ethers.js/issues/201 2018-06-14 12:31:57 -07:00
Leonid Logvinov
6395c2a8b2 Update changelogs 2018-06-04 11:19:59 -07:00
Leonid Logvinov
c8225288cd v0.7.0 2018-06-04 11:15:00 -07:00
Leonid Logvinov
4a108aa67d Set default params and jsonrpc in Web3Wrapper._sendRawPayloadAsync 2018-06-04 11:11:18 -07:00
Leonid Logvinov
fd9b3e0dcf Add default jsonRpcId to raw payloads sent from web3Wrapper 2018-06-01 16:01:04 -07:00
Leonid Logvinov
f94b647e61 Publish
- 0x.js@0.38.3
 - contracts@2.1.32
 - @0xproject/order-watcher@0.0.5
 - @0xproject/sra-report@0.1.3
 - @0xproject/testnet-faucets@1.0.33
 - @0xproject/website@0.0.36
2018-05-29 11:29:07 -07:00
Leonid Logvinov
2eccc3efaf Updated CHANGELOGS 2018-05-29 11:29:01 -07:00
Leonid Logvinov
972341725e Remove UMD bundles from order-watcher 2018-05-29 11:13:50 -07:00
Leonid Logvinov
40b10fd29d Publish
- 0x.js@0.38.2
 - @0xproject/contract-wrappers@0.0.4
 - contracts@2.1.31
 - @0xproject/order-watcher@0.0.4
 - @0xproject/sra-report@0.1.2
 - @0xproject/testnet-faucets@1.0.32
 - @0xproject/website@0.0.35
2018-05-29 11:12:33 -07:00
Leonid Logvinov
b31fcffc76 Updated CHANGELOGS 2018-05-29 11:12:26 -07:00
Leonid Logvinov
ec222ea0cd Remove UMD bundles from contract-wrappers 2018-05-29 11:04:00 -07:00
Leonid Logvinov
5533220da0 Publish
- 0x.js@0.38.1
 - @0xproject/connect@0.6.14
 - @0xproject/contract-wrappers@0.0.3
 - contracts@2.1.30
 - @0xproject/fill-scenarios@0.0.3
 - @0xproject/order-utils@0.0.6
 - @0xproject/order-watcher@0.0.3
 - @0xproject/sra-report@0.1.1
 - @0xproject/testnet-faucets@1.0.31
 - @0xproject/website@0.0.34
2018-05-29 11:01:25 -07:00
Leonid Logvinov
6ee7024457 Updated CHANGELOGS 2018-05-29 11:01:18 -07:00
Fabio Berger
f839ac9c58 Merge branch 'development' of github.com:0xProject/0x-monorepo into development
* 'development' of github.com:0xProject/0x-monorepo:
  Correct documentation variable name
  Publish
  Updated CHANGELOGS
  Updated CHANGELOGS
  Change publish command name
2018-05-22 16:39:15 -07:00
Fabio Berger
1a8b1460a6 Fix signature verification test 2018-05-22 16:38:57 -07:00
Leonid Logvinov
feac0779a4 Merge pull request #608 from prettymuchbryce/docs-fix
Correct documentation variable name
2018-05-22 15:38:27 -07:00
Bryce Neal
d9eeb0421c Correct documentation variable name 2018-05-22 13:37:38 -07:00
462 changed files with 10463 additions and 28687 deletions

View File

@@ -11,27 +11,23 @@ jobs:
- checkout
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
- yarn-packages-{{ .Branch }}
- yarn-packages-master
- yarn-packages-
key: dependency-cache-v1-{{ checksum "package.json" }}
- run:
name: yarn
command: yarn --frozen-lockfile install
command: yarn --frozen-lockfile
- save_cache:
name: Save Yarn Package Cache
key: yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
key: dependency-cache-v1-{{ checksum "package.json" }}
paths:
- node_modules/
- ./node_modules
- run: wget https://s3.amazonaws.com/testrpc-shapshots/${CONTRACTS_COMMIT_HASH}.zip
- run: unzip ${CONTRACTS_COMMIT_HASH}.zip -d testrpc_snapshot
- run: node ./node_modules/lerna/bin/lerna.js bootstrap
- run: yarn build
- save_cache:
key: repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo
test-1:
test-installation:
docker:
- image: circleci/node:9
working_directory: ~/repo
@@ -39,16 +35,24 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0xproject/contract-wrappers
- run: yarn wsrun test:circleci @0xproject/sol-compiler
- run: yarn test:installation
test-0xjs:
docker:
- image: circleci/node:9
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn wsrun test:circleci 0x.js
- save_cache:
key: coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
key: coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/contract-wrappers/coverage/lcov.info
- save_cache:
key: coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/sol-compiler/coverage/lcov.info
- ~/repo/packages/0x.js/coverage/lcov.info
test-contracts:
docker:
- image: circleci/node:9
@@ -57,8 +61,16 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn wsrun test:circleci contracts
test-2:
- save_cache:
key: coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/contracts/coverage/lcov.info
test-sol-compiler:
docker:
- image: circleci/node:9
working_directory: ~/repo
@@ -66,13 +78,28 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0xproject/assert
- run: yarn wsrun test:circleci @0xproject/connect
- run: yarn wsrun test:circleci @0xproject/dev-utils
- run: yarn wsrun test:circleci @0xproject/json-schemas
- run: yarn wsrun test:circleci @0xproject/subproviders
- run: yarn wsrun test:circleci @0xproject/sol-cov
- run: yarn wsrun test:circleci @0xproject/metacoin
- run:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn wsrun test:circleci @0xproject/sol-compiler
- save_cache:
key: coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/sol-compiler/coverage/lcov.info
test-rest:
docker:
- image: circleci/node:9
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn wsrun test:circleci --exclude contracts --exclude 0x.js --exclude @0xproject/sol-compiler --stages --exclude-missing
- save_cache:
key: coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -101,7 +128,16 @@ jobs:
key: coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/metacoin/coverage/lcov.info
static-tests:
lint:
working_directory: ~/repo
docker:
- image: circleci/node:9
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn lerna:run lint
prettier:
working_directory: ~/repo
docker:
- image: circleci/node:9
@@ -110,7 +146,6 @@ jobs:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn prettier:ci
- run: yarn lerna:run lint
submit-coverage:
docker:
- image: circleci/node:9
@@ -119,15 +154,15 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
@@ -140,9 +175,6 @@ jobs:
- restore_cache:
keys:
- coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
@@ -158,19 +190,30 @@ workflows:
main:
jobs:
- build
- test-1:
- test-installation:
requires:
- build
- test-2:
- test-0xjs:
requires:
- build
- test-contracts:
requires:
- build
- static-tests:
- test-sol-compiler:
requires:
- build
- test-rest:
requires:
- build
- prettier:
requires:
- build
- lint:
requires:
- build
- submit-coverage:
requires:
- test-1
- test-2
- test-0xjs
- test-sol-compiler
- test-rest
- test-contracts

5
.gitignore vendored
View File

@@ -86,11 +86,12 @@ packages/contract-wrappers/src/contract_wrappers/generated/
packages/metacoin/src/contract_wrappers
packages/fill-scenarios/src/generated_contract_wrappers/
packages/order-watcher/src/generated_contract_wrappers/
packages/migrations/src/v1/contract_wrappers
packages/migrations/src/v2/contract_wrappers
packages/migrations/src/contract_wrappers
# solc-bin in sol-compiler
packages/sol-compiler/solc_bin/
# Monorepo scripts
packages/*/scripts/
ganache.log

View File

@@ -6,6 +6,5 @@ lib
/packages/contract-wrappers/test/artifacts
/packages/order-watcher/test/artifacts
/packages/migrations/artifacts/1.0.0
/packages/migrations/artifacts/2.0.0
package.json
scripts/postpublish_utils.js

View File

@@ -13,8 +13,9 @@
"prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}' --config .prettierrc",
"report_coverage": "lcov-result-merger 'packages/*/coverage/lcov.info' | coveralls",
"test:installation": "node ./packages/monorepo-scripts/lib/test_installation.js",
"run:publish": "run-s install:all rebuild script:publish",
"run:publish:dry": "run-s install:all rebuild script:publish:dry",
"run:publish": "run-s install:all build:monorepo_scripts script:prepublish_checks rebuild script:publish",
"run:publish:dry": "run-s install:all build:monorepo_scripts script:prepublish_checks rebuild script:publish:dry",
"script:prepublish_checks": "node ./packages/monorepo-scripts/lib/prepublish_checks.js",
"script:publish": "node ./packages/monorepo-scripts/lib/publish.js",
"script:publish:dry": "IS_DRY_RUN=true yarn script:publish",
"install:all": "yarn install",
@@ -22,26 +23,24 @@
"lerna:run": "lerna run",
"watch": "wsrun watch $PKG --fast-exit -r --stages --done-criteria='complete|successfully'",
"build": "wsrun build $PKG --fast-exit -r --stages",
"build:monorepo_scripts": "PKG=@0xproject/monorepo-scripts yarn build",
"clean": "wsrun clean $PKG --fast-exit -r --parallel",
"rebuild": "run-s clean build",
"test": "wsrun test $PKG --fast-exit --serial --exclude-missing",
"stage_docs": "wsrun docs:stage $PKG --fast-exit --parallel --exclude-missing",
"lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing"
"test": "wsrun test $PKG --serial --exclude-missing",
"stage_docs": "wsrun docs:stage $PKG --parallel --exclude-missing",
"lint": "wsrun lint $PKG --parallel --exclude-missing"
},
"config": {
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
},
"devDependencies": {
"async-child-process": "^1.1.1",
"async-child-process": "1.1.1",
"coveralls": "^3.0.0",
"ganache-cli": "^6.1.0",
"lcov-result-merger": "^3.0.0",
"lerna": "^2.5.1",
"npm-run-all": "^4.1.2",
"prettier": "^1.11.1",
"npm-run-all": "4.1.2",
"prettier": "1.12.1",
"wsrun": "^2.2.0"
},
"resolutions": {
"ethereumjs-tx": "0xProject/ethereumjs-tx#fake-tx-include-signature-by-default"
}
}

View File

@@ -9,3 +9,5 @@ test/
/generated_docs/
/scripts/
/lib/src/monorepo_scripts/
/lib/test/
ganache.log

View File

@@ -1,6 +1,42 @@
[
{
"timestamp": 1527809861,
"timestamp": 1531149657,
"version": "0.38.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1529397769,
"version": "0.38.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527617805,
"version": "0.38.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527617227,
"version": "0.38.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527616612,
"version": "0.38.1",
"changes": [
{

View File

@@ -5,7 +5,23 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.38.1 - _May 31, 2018_
## v0.38.5 - _July 9, 2018_
* Dependencies updated
## v0.38.4 - _June 19, 2018_
* Dependencies updated
## v0.38.3 - _May 29, 2018_
* Dependencies updated
## v0.38.2 - _May 29, 2018_
* Dependencies updated
## v0.38.1 - _May 29, 2018_
* Dependencies updated
@@ -14,7 +30,7 @@ CHANGELOG
* Renamed createOrderStateWatcher to createOrderWatcherAsync since it is now async (#579)
* Renamed ZeroExError to ContractWrappersErrors since they now lives in the @0xproject/contract-wrappers subpackage (#579)
## v0.37.2 - _May 4, 2018_
## v0.37.2 - _May 5, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "0x.js",
"version": "0.38.0",
"version": "0.38.5",
"engines": {
"node": ">=6.12"
},
@@ -44,7 +44,6 @@
"docPublishConfigs": {
"extraFileIncludes": [
"../types/src/index.ts",
"../ethereum-types/src/index.ts",
"../contract-wrappers/src/types.ts",
"../contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts",
"../contract-wrappers/src/contract_wrappers/exchange_wrapper.ts",
@@ -67,51 +66,49 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@0xproject/abi-gen": "^0.3.0",
"@0xproject/dev-utils": "^0.4.2",
"@0xproject/migrations": "^0.0.6",
"@0xproject/monorepo-scripts": "^0.1.20",
"@0xproject/sol-compiler": "^0.5.0",
"@0xproject/tslint-config": "^0.4.18",
"@0xproject/abi-gen": "^0.3.3",
"@0xproject/dev-utils": "^0.4.5",
"@0xproject/migrations": "^0.0.9",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/node": "^8.0.53",
"@types/sinon": "^2.2.2",
"awesome-typescript-loader": "^3.1.3",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^2.0.1",
"copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1",
"json-loader": "^0.5.4",
"make-promises-safe": "^1.1.0",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"opn-cli": "^3.1.0",
"prettier": "^1.11.1",
"shx": "^0.2.2",
"sinon": "^4.0.0",
"source-map-support": "^0.5.0",
"@types/mocha": "2.2.48",
"@types/node": "9.6.0",
"@types/sinon": "2.3.7",
"awesome-typescript-loader": "3.5.0",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"chai-bignumber": "2.0.1",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"json-loader": "0.5.7",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"nyc": "11.6.0",
"opn-cli": "3.1.0",
"prettier": "1.12.1",
"shx": "0.2.2",
"sinon": "4.4.9",
"source-map-support": "0.5.4",
"tslint": "5.8.0",
"typedoc": "0xProject/typedoc",
"typescript": "2.7.1",
"webpack": "^3.1.0"
"webpack": "3.11.0"
},
"dependencies": {
"@0xproject/assert": "^0.2.10",
"@0xproject/base-contract": "^0.3.2",
"@0xproject/contract-wrappers": "^0.0.2",
"@0xproject/order-utils": "^0.0.5",
"@0xproject/order-watcher": "^0.0.2",
"@0xproject/sol-compiler": "^0.5.0",
"@0xproject/types": "0.7.0",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
"@0xproject/web3-wrapper": "^0.6.4",
"ethereum-types": "^0.0.1",
"ethers": "^3.0.15",
"lodash": "^4.17.4"
"@0xproject/assert": "^0.2.13",
"@0xproject/base-contract": "^0.3.5",
"@0xproject/contract-wrappers": "^0.1.0",
"@0xproject/order-utils": "^0.0.8",
"@0xproject/order-watcher": "^0.0.7",
"@0xproject/sol-compiler": "^0.5.3",
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.2",
"@0xproject/web3-wrapper": "^0.7.2",
"ethers": "3.0.22",
"lodash": "4.17.10"
},
"publishConfig": {
"access": "public"

View File

@@ -19,6 +19,8 @@ export {
TransactionReceiptWithDecodedLogs,
} from '@0xproject/types';
export { OrderWatcherConfig } from '@0xproject/order-watcher';
export {
EventCallback,
ContractEvent,

View File

@@ -15,7 +15,7 @@ const TIMEOUT = 10000;
describe('Artifacts', () => {
describe('contracts are deployed on kovan', () => {
const kovanRpcUrl = constants.KOVAN_RPC_URL;
const provider = web3Factory.getRpcProvider({ rpcUrl: kovanRpcUrl });
const provider = web3Factory.create({ rpcUrl: kovanRpcUrl }).currentProvider;
const config = {
networkId: constants.KOVAN_NETWORK_ID,
};
@@ -32,7 +32,7 @@ describe('Artifacts', () => {
});
describe('contracts are deployed on ropsten', () => {
const ropstenRpcUrl = constants.ROPSTEN_RPC_URL;
const provider = web3Factory.getRpcProvider({ rpcUrl: ropstenRpcUrl });
const provider = web3Factory.create({ rpcUrl: ropstenRpcUrl }).currentProvider;
const config = {
networkId: constants.ROPSTEN_NETWORK_ID,
};

View File

@@ -1,5 +1,5 @@
import { devConstants } from '@0xproject/dev-utils';
import { runV1MigrationsAsync } from '@0xproject/migrations';
import { runMigrationsAsync } from '@0xproject/migrations';
import * as path from 'path';
import { constants } from './utils/constants';
@@ -11,9 +11,9 @@ before('migrate contracts', async function(): Promise<void> {
const mochaTestTimeoutMs = 20000;
this.timeout(mochaTestTimeoutMs);
const txDefaults = {
gas: devConstants.GAS_LIMIT,
gas: devConstants.GAS_ESTIMATE,
from: devConstants.TESTRPC_FIRST_ADDRESS,
};
const artifactsDir = `../migrations/artifacts/1.0.0`;
await runV1MigrationsAsync(provider, artifactsDir, txDefaults);
await runMigrationsAsync(provider, artifactsDir, txDefaults);
});

View File

@@ -2,7 +2,8 @@ import { devConstants, web3Factory } from '@0xproject/dev-utils';
import { Provider } from '@0xproject/types';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true });
const web3Wrapper = new Web3Wrapper(provider);
const web3 = web3Factory.create({ shouldUseInProcessGanache: true });
const provider: Provider = web3.currentProvider;
const web3Wrapper = new Web3Wrapper(web3.currentProvider);
export { provider, web3Wrapper };

View File

@@ -1,13 +1,31 @@
[
{
"timestamp": 1527809861,
"version": "0.3.1",
"timestamp": 1531149657,
"version": "0.3.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1529397769,
"version": "0.3.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.3.1",
"changes": [
{
"note": "Incorrect publish that was unpublished"
}
],
"timestamp": 1527810075
},
{
"version": "0.3.0",
"changes": [

View File

@@ -5,15 +5,23 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.3.1 - _May 31, 2018_
## v0.3.3 - _July 9, 2018_
* Dependencies updated
## v0.3.2 - _June 19, 2018_
* Dependencies updated
## v0.3.1 - _June 1, 2018_
* Incorrect publish that was unpublished
## v0.3.0 - _May 22, 2018_
* Properly export the executable binary (#588)
## v0.2.13 - _May 4, 2018_
## v0.2.13 - _May 5, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/abi-gen",
"version": "0.3.0",
"version": "0.3.3",
"engines": {
"node": ">=6.12"
},
@@ -27,29 +27,29 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
"dependencies": {
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
"ethereum-types": "^0.0.1",
"chalk": "^2.3.0",
"glob": "^7.1.2",
"handlebars": "^4.0.11",
"lodash": "^4.17.4",
"mkdirp": "^0.5.1",
"to-snake-case": "^1.0.0",
"yargs": "^10.0.3"
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.2",
"chalk": "2.3.2",
"glob": "7.1.1",
"handlebars": "4.0.11",
"lodash": "4.17.10",
"mkdirp": "0.5.1",
"to-snake-case": "1.0.0",
"yargs": "11.1.0"
},
"devDependencies": {
"@0xproject/monorepo-scripts": "^0.1.20",
"@0xproject/tslint-config": "^0.4.18",
"@types/glob": "^5.0.33",
"@types/handlebars": "^4.0.36",
"@types/mkdirp": "^0.5.1",
"@types/node": "^8.0.53",
"@types/yargs": "^10.0.0",
"copyfiles": "^1.2.0",
"make-promises-safe": "^1.1.0",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/glob": "5.0.35",
"@types/handlebars": "4.0.36",
"@types/mkdirp": "0.5.2",
"@types/node": "9.6.0",
"@types/yargs": "10.0.2",
"copyfiles": "1.2.0",
"make-promises-safe": "1.1.0",
"npm-run-all": "4.1.2",
"shx": "0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1"
},

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env node
import { AbiDefinition, ConstructorAbi, EventAbi, MethodAbi } from '@0xproject/types';
import { abiUtils, logUtils } from '@0xproject/utils';
import chalk from 'chalk';
import { AbiDefinition, ConstructorAbi, EventAbi, MethodAbi } from 'ethereum-types';
import * as fs from 'fs';
import { sync as globSync } from 'glob';
import * as Handlebars from 'handlebars';

View File

@@ -1,4 +1,4 @@
import { EventAbi, MethodAbi } from 'ethereum-types';
import { EventAbi, MethodAbi } from '@0xproject/types';
export enum ParamKind {
Input = 'input',

View File

@@ -1,4 +1,4 @@
import { AbiType, ConstructorAbi, DataItem } from 'ethereum-types';
import { AbiType, ConstructorAbi, DataItem } from '@0xproject/types';
import * as fs from 'fs';
import * as _ from 'lodash';
import * as path from 'path';

View File

@@ -1,13 +1,31 @@
[
{
"timestamp": 1527809861,
"version": "0.2.11",
"timestamp": 1531149657,
"version": "0.2.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1529397769,
"version": "0.2.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.2.11",
"changes": [
{
"note": "Incorrect publish that was unpublished"
}
],
"timestamp": 1527810075
},
{
"timestamp": 1527008270,
"version": "0.2.10",

View File

@@ -5,15 +5,23 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.2.11 - _May 31, 2018_
## v0.2.13 - _July 9, 2018_
* Dependencies updated
## v0.2.12 - _June 19, 2018_
* Dependencies updated
## v0.2.11 - _June 1, 2018_
* Incorrect publish that was unpublished
## v0.2.10 - _May 22, 2018_
* Dependencies updated
## v0.2.9 - _May 4, 2018_
## v0.2.9 - _May 5, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/assert",
"version": "0.2.10",
"version": "0.2.13",
"engines": {
"node": ">=6.12"
},
@@ -30,28 +30,28 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
"devDependencies": {
"@0xproject/monorepo-scripts": "^0.1.20",
"@0xproject/tslint-config": "^0.4.18",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/valid-url": "^1.0.2",
"chai": "^4.0.1",
"copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1",
"make-promises-safe": "^1.1.0",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"shx": "^0.2.2",
"@types/mocha": "2.2.48",
"@types/valid-url": "1.0.2",
"chai": "4.1.2",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"nyc": "11.6.0",
"shx": "0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1"
},
"dependencies": {
"@0xproject/json-schemas": "0.7.22",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
"lodash": "^4.17.4",
"valid-url": "^1.0.9"
"@0xproject/json-schemas": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.2",
"lodash": "4.17.10",
"valid-url": "1.0.9"
},
"publishConfig": {
"access": "public"

View File

@@ -64,9 +64,6 @@ export const assert = {
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Provider', value));
},
doesConformToSchema(variableName: string, value: any, schema: Schema, subSchemas?: Schema[]): void {
if (_.isUndefined(value)) {
throw new Error(`${variableName} can't be undefined`);
}
const schemaValidator = new SchemaValidator();
if (!_.isUndefined(subSchemas)) {
_.map(subSchemas, schemaValidator.addSchema.bind(schemaValidator));

View File

@@ -1,13 +1,32 @@
[
{
"timestamp": 1527809861,
"version": "0.3.3",
"timestamp": 1531149657,
"version": "0.3.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.3.4",
"changes": [
{
"note":
"Update EthersJs to fix the `value.toLowerCase()` is not a function bug caused by `ethers.js` breaking patch version https://github.com/ethers-io/ethers.js/issues/201"
}
],
"timestamp": 1529397769
},
{
"timestamp": 1527810075,
"version": "0.3.3",
"changes": [
{
"note": "Incorrect publish that was unpublished"
}
]
},
{
"timestamp": 1527008270,
"version": "0.3.2",

View File

@@ -5,15 +5,23 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.3.3 - _May 31, 2018_
## v0.3.5 - _July 9, 2018_
* Dependencies updated
## v0.3.4 - _June 19, 2018_
* Update EthersJs to fix the `value.toLowerCase()` is not a function bug caused by `ethers.js` breaking patch version https://github.com/ethers-io/ethers.js/issues/201
## v0.3.3 - _June 1, 2018_
* Incorrect publish that was unpublished
## v0.3.2 - _May 22, 2018_
* Dependencies updated
## v0.3.1 - _May 4, 2018_
## v0.3.1 - _May 5, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/base-contract",
"version": "0.3.2",
"version": "0.3.5",
"engines": {
"node": ">=6.12"
},
@@ -29,25 +29,25 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
"devDependencies": {
"@0xproject/monorepo-scripts": "^0.1.20",
"@0xproject/tslint-config": "^0.4.18",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/lodash": "4.14.104",
"chai": "^4.0.1",
"copyfiles": "^1.2.0",
"make-promises-safe": "^1.1.0",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"chai": "4.1.2",
"copyfiles": "1.2.0",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"shx": "0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1"
},
"dependencies": {
"ethereum-types": "^0.0.1",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
"@0xproject/web3-wrapper": "^0.6.4",
"ethers": "^3.0.15",
"lodash": "^4.17.4"
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.2",
"@0xproject/web3-wrapper": "^0.7.2",
"ethers": "3.0.22",
"lodash": "4.17.10"
},
"publishConfig": {
"access": "public"

View File

@@ -1,5 +1,3 @@
import { abiUtils, BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import {
AbiDefinition,
AbiType,
@@ -10,7 +8,9 @@ import {
Provider,
TxData,
TxDataPayable,
} from 'ethereum-types';
} from '@0xproject/types';
import { abiUtils, BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as ethers from 'ethers';
import * as _ from 'lodash';

View File

@@ -1,4 +1,4 @@
import { DataItem } from 'ethereum-types';
import { DataItem } from '@0xproject/types';
import * as _ from 'lodash';
// tslint:disable-next-line:completed-docs

View File

@@ -1,6 +1,24 @@
[
{
"timestamp": 1527809861,
"timestamp": 1531149657,
"version": "0.6.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1529397769,
"version": "0.6.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527616612,
"version": "0.6.14",
"changes": [
{

View File

@@ -5,7 +5,15 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.6.14 - _May 31, 2018_
## v0.6.16 - _July 9, 2018_
* Dependencies updated
## v0.6.15 - _June 19, 2018_
* Dependencies updated
## v0.6.14 - _May 29, 2018_
* Dependencies updated
@@ -13,7 +21,7 @@ CHANGELOG
* Dependencies updated
## v0.6.12 - _May 4, 2018_
## v0.6.12 - _May 5, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/connect",
"version": "0.6.13",
"version": "0.6.16",
"engines": {
"node": ">=6.12"
},
@@ -50,37 +50,37 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
"dependencies": {
"@0xproject/assert": "^0.2.10",
"@0xproject/json-schemas": "0.7.22",
"@0xproject/types": "^0.7.0",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.17.4",
"query-string": "^5.0.1",
"websocket": "^1.0.25"
"@0xproject/assert": "^0.2.13",
"@0xproject/json-schemas": "^0.8.2",
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.2",
"isomorphic-fetch": "2.2.1",
"lodash": "4.17.10",
"query-string": "4.3.4",
"websocket": "1.0.25"
},
"devDependencies": {
"@0xproject/monorepo-scripts": "^0.1.20",
"@0xproject/tslint-config": "^0.4.18",
"@types/fetch-mock": "^5.12.1",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/fetch-mock": "5.12.2",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/query-string": "^5.0.1",
"@types/websocket": "^0.0.34",
"async-child-process": "^1.1.1",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1",
"fetch-mock": "^5.13.1",
"make-promises-safe": "^1.1.0",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"shx": "^0.2.2",
"@types/mocha": "2.2.48",
"@types/query-string": "5.1.0",
"@types/websocket": "0.0.34",
"async-child-process": "1.1.1",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"fetch-mock": "5.13.1",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"nyc": "11.6.0",
"shx": "0.2.2",
"tslint": "5.8.0",
"typedoc": "~0.8.0",
"typedoc": "0.8.0",
"typescript": "2.7.1"
},
"publishConfig": {

View File

@@ -17,4 +17,4 @@ export {
WebSocketOrderbookChannelConfig,
} from './types';
export { Order, SignedOrder } from '@0xproject/types';
export { ECSignature, Order, SignedOrder } from '@0xproject/types';

View File

@@ -1,4 +1,4 @@
import { Order, SignedOrder } from '@0xproject/types';
import { ECSignature, Order, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
export interface Client {
@@ -16,7 +16,7 @@ export interface OrderbookChannel {
}
/**
* heartbeatInterval: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000
* heartbeatIntervalMs: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000
*/
export interface WebSocketOrderbookChannelConfig {
heartbeatIntervalMs?: number;

View File

@@ -1,6 +1,34 @@
[
{
"timestamp": 1527809861,
"version": "0.1.0",
"changes": [
{
"note":
"Update Blockstream dep. to V5.0 and no longer force unsubscribe on blockstream error (which are not recoverable)"
}
],
"timestamp": 1531149657
},
{
"timestamp": 1529397769,
"version": "0.0.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527617227,
"version": "0.0.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527616612,
"version": "0.0.3",
"changes": [
{

View File

@@ -5,7 +5,19 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.0.3 - _May 31, 2018_
## v0.1.0 - _July 9, 2018_
* Update Blockstream dep. to V5.0 and no longer force unsubscribe on blockstream error (which are not recoverable)
## v0.0.5 - _June 19, 2018_
* Dependencies updated
## v0.0.4 - _May 29, 2018_
* Dependencies updated
## v0.0.3 - _May 29, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/contract-wrappers",
"version": "0.0.2",
"version": "0.1.0",
"description": "Smart TS wrappers for 0x smart contracts",
"keywords": [
"0xproject",
@@ -27,13 +27,7 @@
},
"config": {
"compact_artifacts": "Exchange DummyToken ZRXToken Token EtherToken TokenTransferProxy TokenRegistry",
"contracts": "Exchange DummyToken ZRXToken Token WETH9 TokenTransferProxy_v1 MultiSigWallet MultiSigWalletWithTimeLock MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress MaliciousToken TokenRegistry Arbitrage EtherDelta AccountLevels",
"postpublish": {
"assets": [
"packages/contract-wrappers/_bundles/index.js",
"packages/contract-wrappers/_bundles/index.min.js"
]
}
"contracts": "Exchange DummyToken ZRXToken Token WETH9 TokenTransferProxy MultiSigWallet MultiSigWalletWithTimeLock MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress MaliciousToken TokenRegistry Arbitrage EtherDelta AccountLevels"
},
"repository": {
"type": "git",
@@ -44,54 +38,53 @@
"node": ">=6.0.0"
},
"devDependencies": {
"@0xproject/abi-gen": "^0.3.0",
"@0xproject/dev-utils": "^0.4.2",
"@0xproject/migrations": "^0.0.6",
"@0xproject/monorepo-scripts": "^0.1.20",
"@0xproject/sol-compiler": "^0.5.0",
"@0xproject/subproviders": "^0.10.2",
"@0xproject/tslint-config": "^0.4.18",
"@0xproject/abi-gen": "^0.3.3",
"@0xproject/dev-utils": "^0.4.5",
"@0xproject/migrations": "^0.0.9",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/sol-compiler": "^0.5.3",
"@0xproject/subproviders": "^0.10.5",
"@0xproject/tslint-config": "^0.4.21",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/node": "^8.0.53",
"@types/sinon": "^2.2.2",
"@types/uuid": "^3.4.2",
"awesome-typescript-loader": "^3.1.3",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^2.0.1",
"copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1",
"make-promises-safe": "^1.1.0",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"opn-cli": "^3.1.0",
"prettier": "^1.11.1",
"shx": "^0.2.2",
"sinon": "^4.0.0",
"source-map-support": "^0.5.0",
"@types/mocha": "2.2.48",
"@types/node": "9.6.0",
"@types/sinon": "2.3.7",
"@types/uuid": "3.4.3",
"awesome-typescript-loader": "3.5.0",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"chai-bignumber": "2.0.1",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"nyc": "11.6.0",
"opn-cli": "3.1.0",
"prettier": "1.12.1",
"shx": "0.2.2",
"sinon": "4.4.9",
"source-map-support": "0.5.4",
"tslint": "5.8.0",
"typescript": "2.7.1",
"web3-provider-engine": "^14.0.4"
"web3-provider-engine": "13.8.0"
},
"dependencies": {
"@0xproject/assert": "^0.2.10",
"@0xproject/base-contract": "^0.3.2",
"@0xproject/fill-scenarios": "^0.0.2",
"@0xproject/json-schemas": "0.7.22",
"@0xproject/order-utils": "^0.0.5",
"@0xproject/types": "0.7.0",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
"@0xproject/web3-wrapper": "^0.6.4",
"ethereum-types": "^0.0.1",
"ethereumjs-blockstream": "^2.0.6",
"ethereumjs-util": "^5.1.1",
"ethers": "^3.0.15",
"js-sha3": "^0.7.0",
"lodash": "^4.17.4",
"uuid": "^3.1.0"
"@0xproject/assert": "^0.2.13",
"@0xproject/base-contract": "^0.3.5",
"@0xproject/fill-scenarios": "^0.0.5",
"@0xproject/json-schemas": "^0.8.2",
"@0xproject/order-utils": "^0.0.8",
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.2",
"@0xproject/web3-wrapper": "^0.7.2",
"ethereumjs-blockstream": "5.0.0",
"ethereumjs-util": "5.1.5",
"ethers": "3.0.22",
"js-sha3": "0.7.0",
"lodash": "4.17.10",
"uuid": "3.2.1"
},
"publishConfig": {
"access": "public"

View File

@@ -9,7 +9,7 @@ import {
} from '@0xproject/types';
import { AbiDecoder, intervalUtils } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Block, BlockAndLogStreamer } from 'ethereumjs-blockstream';
import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream';
import * as _ from 'lodash';
import {
@@ -38,7 +38,7 @@ const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {
export class ContractWrapper {
protected _web3Wrapper: Web3Wrapper;
protected _networkId: number;
private _blockAndLogStreamerIfExists?: BlockAndLogStreamer;
private _blockAndLogStreamerIfExists?: BlockAndLogStreamer<Block, Log> | undefined;
private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer;
private _filters: { [filterToken: string]: FilterObject };
private _filterCallbacks: {
@@ -46,6 +46,10 @@ export class ContractWrapper {
};
private _onLogAddedSubscriptionToken: string | undefined;
private _onLogRemovedSubscriptionToken: string | undefined;
private static _onBlockstreamError(err: Error): void {
// Noop on blockstream errors since they are automatically
// recovered from and don't cause Blockstream to exit.
}
constructor(web3Wrapper: Web3Wrapper, networkId: number) {
this._web3Wrapper = web3Wrapper;
this._networkId = networkId;
@@ -162,13 +166,14 @@ export class ContractWrapper {
this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
ContractWrapper._onBlockstreamError.bind(this),
);
const catchAllLogFilter = {};
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
this._blockAndLogStreamIntervalIfExists = intervalUtils.setAsyncExcludingInterval(
this._reconcileBlockAsync.bind(this),
constants.DEFAULT_BLOCK_POLLING_INTERVAL,
this._onReconcileBlockError.bind(this),
ContractWrapper._onBlockstreamError.bind(this),
);
let isRemoved = false;
this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
@@ -179,12 +184,6 @@ export class ContractWrapper {
this._onLogStateChanged.bind(this, isRemoved),
);
}
private _onReconcileBlockError(err: Error): void {
const filterTokens = _.keys(this._filterCallbacks);
_.each(filterTokens, filterToken => {
this._unsubscribe(filterToken, err);
});
}
private _setNetworkId(networkId: number): void {
this._networkId = networkId;
}

View File

@@ -15,7 +15,7 @@ const TIMEOUT = 10000;
describe('Artifacts', () => {
describe('contracts are deployed on kovan', () => {
const kovanRpcUrl = constants.KOVAN_RPC_URL;
const provider = web3Factory.getRpcProvider({ rpcUrl: kovanRpcUrl });
const provider = web3Factory.create({ rpcUrl: kovanRpcUrl }).currentProvider;
const config = {
networkId: constants.KOVAN_NETWORK_ID,
};
@@ -32,7 +32,7 @@ describe('Artifacts', () => {
});
describe('contracts are deployed on ropsten', () => {
const ropstenRpcUrl = constants.ROPSTEN_RPC_URL;
const provider = web3Factory.getRpcProvider({ rpcUrl: ropstenRpcUrl });
const provider = web3Factory.create({ rpcUrl: ropstenRpcUrl }).currentProvider;
const config = {
networkId: constants.ROPSTEN_NETWORK_ID,
};

View File

@@ -95,7 +95,7 @@ describe('EtherTokenWrapper', () => {
depositWeiAmount,
addressWithETH,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const postETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync(
@@ -137,7 +137,7 @@ describe('EtherTokenWrapper', () => {
depositWeiAmount,
addressWithETH,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const postETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync(
@@ -347,7 +347,7 @@ describe('EtherTokenWrapper', () => {
});
it('should get logs with decoded args emitted by Approval', async () => {
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = EtherTokenEvents.Approval;
const indexFilterValues = {};
const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>(
@@ -381,7 +381,7 @@ describe('EtherTokenWrapper', () => {
});
it('should only get the logs with the correct event name', async () => {
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const differentEventName = EtherTokenEvents.Transfer;
const indexFilterValues = {};
const logs = await contractWrappers.etherToken.getLogsAsync(
@@ -394,12 +394,12 @@ describe('EtherTokenWrapper', () => {
});
it('should only get the logs with the correct indexed fields', async () => {
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(
etherTokenAddress,
addressWithoutFunds,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = EtherTokenEvents.Approval;
const indexFilterValues = {
_owner: addressWithETH,

View File

@@ -60,7 +60,7 @@ describe('ExchangeTransferSimulator', () => {
});
it("throws if the user doesn't have enough balance", async () => {
txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
return expect(
exchangeTransferSimulator.transferFromAsync(
exampleTokenAddress,
@@ -74,9 +74,9 @@ describe('ExchangeTransferSimulator', () => {
});
it('updates balances and proxyAllowance after transfer', async () => {
txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
await exchangeTransferSimulator.transferFromAsync(
exampleTokenAddress,
sender,
@@ -95,9 +95,9 @@ describe('ExchangeTransferSimulator', () => {
});
it("doesn't update proxyAllowance after transfer if unlimited", async () => {
txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
await exchangeTransferSimulator.transferFromAsync(
exampleTokenAddress,
sender,

View File

@@ -276,7 +276,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
expect(
await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
@@ -305,7 +305,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
expect(
await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
@@ -338,7 +338,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
expect(
await contractWrappers.token.getBalanceAsync(zrxTokenAddress, feeRecipient),
).to.be.bignumber.equal(makerFee.plus(takerFee));
@@ -469,7 +469,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
anotherOrderHashHex,
@@ -595,7 +595,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
anotherOrderHashHex,
@@ -611,7 +611,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
const zeroAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
expect(filledAmount).to.be.bignumber.equal(fillableAmount);
@@ -632,7 +632,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
anotherOrderHashHex,
@@ -730,7 +730,7 @@ describe('ExchangeWrapper', () => {
describe('successful cancels', () => {
it('should cancel an order', async () => {
const txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex);
expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
});
@@ -1112,7 +1112,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = ExchangeEvents.LogFill;
const indexFilterValues = {};
const logs = await contractWrappers.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
@@ -1133,7 +1133,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const differentEventName = ExchangeEvents.LogCancel;
const indexFilterValues = {};
const logs = await contractWrappers.exchange.getLogsAsync(
@@ -1157,7 +1157,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const differentMakerAddress = userAddresses[2];
const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
@@ -1173,7 +1173,7 @@ describe('ExchangeWrapper', () => {
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = ExchangeEvents.LogFill;
const indexFilterValues = {

View File

@@ -1,5 +1,5 @@
import { devConstants } from '@0xproject/dev-utils';
import { runV1MigrationsAsync } from '@0xproject/migrations';
import { runMigrationsAsync } from '@0xproject/migrations';
import * as path from 'path';
import { constants } from './utils/constants';
@@ -11,9 +11,9 @@ before('migrate contracts', async function(): Promise<void> {
const mochaTestTimeoutMs = 20000;
this.timeout(mochaTestTimeoutMs);
const txDefaults = {
gas: devConstants.GAS_LIMIT,
gas: devConstants.GAS_ESTIMATE,
from: devConstants.TESTRPC_FIRST_ADDRESS,
};
const artifactsDir = `../migrations/artifacts/1.0.0`;
await runV1MigrationsAsync(provider, artifactsDir, txDefaults);
await runMigrationsAsync(provider, artifactsDir, txDefaults);
});

View File

@@ -51,34 +51,6 @@ describe('SubscriptionTest', () => {
_.each(stubs, s => s.restore());
stubs = [];
});
it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
(async () => {
const errMsg = 'Error fetching block';
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await contractWrappers.token.setAllowanceAsync(
tokenAddress,
coinbase,
addressWithoutFunds,
allowanceAmount,
);
})().catch(done);
});
it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
(async () => {
const errMsg = 'Error fetching logs';
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await contractWrappers.token.setAllowanceAsync(
tokenAddress,
coinbase,
addressWithoutFunds,
allowanceAmount,
);
})().catch(done);
});
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
(async () => {
const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;

View File

@@ -542,7 +542,7 @@ describe('TokenWrapper', () => {
});
it('should get logs with decoded args emitted by Approval', async () => {
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = TokenEvents.Approval;
const indexFilterValues = {};
const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>(
@@ -560,7 +560,7 @@ describe('TokenWrapper', () => {
});
it('should only get the logs with the correct event name', async () => {
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const differentEventName = TokenEvents.Transfer;
const indexFilterValues = {};
const logs = await contractWrappers.token.getLogsAsync(
@@ -573,9 +573,9 @@ describe('TokenWrapper', () => {
});
it('should only get the logs with the correct indexed fields', async () => {
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = TokenEvents.Approval;
const indexFilterValues = {
_owner: coinbase,

View File

@@ -2,7 +2,8 @@ import { devConstants, web3Factory } from '@0xproject/dev-utils';
import { Provider } from '@0xproject/types';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true });
const web3Wrapper = new Web3Wrapper(provider);
const web3 = web3Factory.create({ shouldUseInProcessGanache: true });
const provider: Provider = web3.currentProvider;
const web3Wrapper = new Web3Wrapper(web3.currentProvider);
export { provider, web3Wrapper };

View File

@@ -2,11 +2,11 @@
* This file is auto-generated using abi-gen. Don't edit directly.
* Templates can be found at https://github.com/0xProject/0x-monorepo/tree/development/packages/contract_templates.
*/
// tslint:disable:no-consecutive-blank-lines ordered-imports
// tslint:disable:no-consecutive-blank-lines
// tslint:disable-next-line:no-unused-variable
import { BaseContract } from '@0xproject/base-contract';
import { ContractArtifact } from '@0xproject/sol-compiler';
import { BlockParam, BlockParamLiteral, CallData, ContractAbi, DataItem, DecodedLogArgs, MethodAbi, Provider, TxData, TxDataPayable } from 'ethereum-types';
import { BlockParam, BlockParamLiteral, CallData, ContractAbi, DataItem, DecodedLogArgs, MethodAbi, Provider, TxData, TxDataPayable } from '@0xproject/types';
import { BigNumber, classUtils, logUtils, promisify } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as ethers from 'ethers';
@@ -31,7 +31,6 @@ export enum {{contractName}}Events {
{{/if}}
// tslint:disable:no-parameter-reassignment
// tslint:disable-next-line:class-name
export class {{contractName}}Contract extends BaseContract {
{{#each methods}}
{{#this.constant}}
@@ -76,7 +75,7 @@ export class {{contractName}}Contract extends BaseContract {
);
const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults);
logUtils.log(`transactionHash: ${txHash}`);
const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(txHash);
logUtils.log(`{{contractName}} successfully deployed at ${txReceipt.contractAddress}`);
const contractInstance = new {{contractName}}Contract(abi, txReceipt.contractAddress as string, provider, txDefaults);
contractInstance.constructorArgs = [{{> params inputs=ctor.inputs}}];

View File

@@ -1,11 +1,7 @@
{
"artifactsDir": "../migrations/artifacts/2.0.0",
"artifactsDir": "../migrations/artifacts/1.0.0",
"contractsDir": "src/contracts",
"compilerSettings": {
"optimizer": {
"enabled": true,
"runs": 0
},
"outputSelection": {
"*": {
"*": [
@@ -19,22 +15,19 @@
}
},
"contracts": [
"AssetProxyOwner",
"DummyERC20Token",
"DummyERC721Token",
"ERC20Proxy",
"ERC721Proxy",
"Exchange",
"MixinAuthorizable",
"DummyToken",
"ZRXToken",
"Token",
"WETH9",
"TokenTransferProxy",
"MultiSigWallet",
"MultiSigWalletWithTimeLock",
"TestAssetProxyDispatcher",
"TestLibBytes",
"TestLibs",
"TestSignatureValidator",
"MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress",
"MaliciousToken",
"TokenRegistry",
"Whitelist",
"WETH9",
"ZRXToken"
"Arbitrage",
"EtherDelta",
"AccountLevels"
]
}

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "contracts",
"version": "2.1.29",
"version": "2.1.34",
"engines": {
"node": ">=6.12"
},
@@ -12,24 +12,24 @@
},
"scripts": {
"watch": "tsc -w",
"prebuild": "run-s clean compile copy_artifacts generate_contract_wrappers",
"copy_artifacts": "copyfiles -u 4 '../migrations/artifacts/2.0.0/**/*' ./lib/src/artifacts;",
"prebuild": "run-s clean copy_artifacts generate_contract_wrappers",
"copy_artifacts": "copyfiles -u 4 '../migrations/artifacts/1.0.0/**/*' ./lib/src/artifacts;",
"build": "tsc",
"test": "run-s build run_mocha",
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
"run_mocha": "mocha 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846",
"compile": "sol-compiler",
"clean": "shx rm -rf lib src/contract_wrappers/generated",
"generate_contract_wrappers":
"abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
"lint": "tslint --project .",
"coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html",
"coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test"
"test:circleci": "yarn test:coverage"
},
"config": {
"abis": "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|TestAssetProxyDispatcher|TestLibBytes|TestLibs|TestSignatureValidator|TokenRegistry|Whitelist|WETH9|ZRXToken).json"
"abis": "../migrations/artifacts/1.0.0/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken|Arbitrage|EtherDelta|AccountLevels|WETH9|MaliciousToken).json"
},
"repository": {
"type": "git",
@@ -42,45 +42,40 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md",
"devDependencies": {
"@0xproject/abi-gen": "^0.3.0",
"@0xproject/dev-utils": "^0.4.2",
"@0xproject/tslint-config": "^0.4.18",
"@0xproject/subproviders": "^0.10.1",
"@0xproject/sol-cov": "^0.0.11",
"@0xproject/abi-gen": "^0.3.3",
"@0xproject/dev-utils": "^0.4.5",
"@0xproject/tslint-config": "^0.4.21",
"@types/lodash": "4.14.104",
"@types/bn.js": "^4.11.0",
"@types/node": "^8.0.53",
"@types/ethereumjs-abi": "^0.6.0",
"@types/yargs": "^10.0.0",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^2.0.1",
"copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1",
"make-promises-safe": "^1.1.0",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"prettier": "^1.11.1",
"shx": "^0.2.2",
"solc": "^0.4.24",
"@types/node": "9.6.0",
"@types/yargs": "10.0.2",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"chai-bignumber": "2.0.1",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"prettier": "1.12.1",
"shx": "0.2.2",
"solc": "0.4.23",
"tslint": "5.8.0",
"typescript": "2.7.1",
"yargs": "^10.0.3"
"yargs": "11.1.0"
},
"dependencies": {
"@0xproject/base-contract": "^0.3.2",
"@0xproject/order-utils": "^0.0.5",
"@0xproject/sol-compiler": "^0.5.0",
"@0xproject/types": "^0.7.0",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
"@0xproject/web3-wrapper": "^0.6.4",
"ethereum-types": "^0.0.1",
"bn.js": "^4.11.8",
"ethereumjs-abi": "^0.6.4",
"ethereumjs-util": "^5.1.1",
"ethers": "^3.0.15",
"lodash": "^4.17.4",
"web3": "^0.20.0"
"0x.js": "^0.38.5",
"@0xproject/base-contract": "^0.3.5",
"@0xproject/sol-compiler": "^0.5.3",
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.2",
"@0xproject/web3-wrapper": "^0.7.2",
"bn.js": "4.11.7",
"ethereumjs-abi": "0.6.5",
"ethereumjs-util": "5.1.5",
"ethers": "3.0.22",
"lodash": "4.17.10",
"web3": "0.20.6"
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
Copyright 2017 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
pragma solidity ^0.4.10;
import "./MultiSigWallet.sol";
import { MultiSigWallet } from "../MultiSigWallet/MultiSigWallet.sol";
/// @title Multisignature wallet with time lock- Allows multiple parties to execute a transaction after a time lock has passed.
/// @author Amir Bandeali - <amir@0xProject.com>

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
Copyright 2017 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
pragma solidity ^0.4.10;
import "../../current/multisig/MultiSigWalletWithTimeLock.sol";
import { MultiSigWalletWithTimeLock } from "../MultiSigWalletWithTimeLock/MultiSigWalletWithTimeLock.sol";
contract MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress is MultiSigWalletWithTimeLock {
@@ -79,4 +79,4 @@ contract MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress is MultiSigWall
}
return true;
}
}
}

View File

@@ -1,87 +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.4.24;
pragma experimental ABIEncoderV2;
import "../../utils/LibBytes/LibBytes.sol";
import "../../tokens/ERC20Token/IERC20Token.sol";
import "./MixinAssetProxy.sol";
import "./MixinAuthorizable.sol";
contract ERC20Proxy is
LibBytes,
MixinAssetProxy,
MixinAuthorizable
{
// Id of this proxy.
uint8 constant PROXY_ID = 1;
// Revert reasons
string constant INVALID_METADATA_LENGTH = "Metadata must have a length of 21.";
string constant TRANSFER_FAILED = "Transfer failed.";
string constant PROXY_ID_MISMATCH = "Proxy id in metadata does not match this proxy id.";
/// @dev Internal version of `transferFrom`.
/// @param assetMetadata Encoded byte array.
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
function transferFromInternal(
bytes memory assetMetadata,
address from,
address to,
uint256 amount
)
internal
{
// Data must be intended for this proxy.
uint256 length = assetMetadata.length;
require(
length == 21,
INVALID_METADATA_LENGTH
);
require(
uint8(assetMetadata[length - 1]) == PROXY_ID,
PROXY_ID_MISMATCH
);
// Decode metadata.
address token = readAddress(assetMetadata, 0);
// Transfer tokens.
bool success = IERC20Token(token).transferFrom(from, to, amount);
require(
success == true,
TRANSFER_FAILED
);
}
/// @dev Gets the proxy id associated with the proxy address.
/// @return Proxy id.
function getProxyId()
external
view
returns (uint8)
{
return PROXY_ID;
}
}

View File

@@ -1,93 +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.4.24;
pragma experimental ABIEncoderV2;
import "../../utils/LibBytes/LibBytes.sol";
import "../../tokens/ERC721Token/ERC721Token.sol";
import "./MixinAssetProxy.sol";
import "./MixinAuthorizable.sol";
contract ERC721Proxy is
LibBytes,
MixinAssetProxy,
MixinAuthorizable
{
// Id of this proxy.
uint8 constant PROXY_ID = 2;
// Revert reasons
string constant INVALID_TRANSFER_AMOUNT = "Transfer amount must equal 1.";
string constant INVALID_METADATA_LENGTH = "Metadata must have a length of 53.";
string constant PROXY_ID_MISMATCH = "Proxy id in metadata does not match this proxy id.";
/// @dev Internal version of `transferFrom`.
/// @param assetMetadata Encoded byte array.
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
function transferFromInternal(
bytes memory assetMetadata,
address from,
address to,
uint256 amount
)
internal
{
// Data must be intended for this proxy.
uint256 length = assetMetadata.length;
require(
length == 53,
INVALID_METADATA_LENGTH
);
require(
uint8(assetMetadata[length - 1]) == PROXY_ID,
PROXY_ID_MISMATCH
);
// There exists only 1 of each token.
require(
amount == 1,
INVALID_TRANSFER_AMOUNT
);
// Decode metadata
address token = readAddress(assetMetadata, 0);
uint256 tokenId = readUint256(assetMetadata, 20);
// Transfer token.
// Either succeeds or throws.
// @TODO: Call safeTransferFrom if there is additional
// data stored in `assetMetadata`.
ERC721Token(token).transferFrom(from, to, tokenId);
}
/// @dev Gets the proxy id associated with the proxy address.
/// @return Proxy id.
function getProxyId()
external
view
returns (uint8)
{
return PROXY_ID;
}
}

View File

@@ -1,75 +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.4.24;
pragma experimental ABIEncoderV2;
import "./mixins/MAssetProxy.sol";
import "./mixins/MAuthorizable.sol";
contract MixinAssetProxy is
MAuthorizable,
MAssetProxy
{
/// @dev Transfers assets. Either succeeds or throws.
/// @param assetMetadata Encoded byte array.
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
function transferFrom(
bytes assetMetadata,
address from,
address to,
uint256 amount
)
external
onlyAuthorized
{
transferFromInternal(
assetMetadata,
from,
to,
amount
);
}
/// @dev Makes multiple transfers of assets. Either succeeds or throws.
/// @param assetMetadata Array of byte arrays encoded for the respective asset proxy.
/// @param from Array of addresses to transfer assets from.
/// @param to Array of addresses to transfer assets to.
/// @param amounts Array of amounts of assets to transfer.
function batchTransferFrom(
bytes[] memory assetMetadata,
address[] memory from,
address[] memory to,
uint256[] memory amounts
)
public
onlyAuthorized
{
for (uint256 i = 0; i < assetMetadata.length; i++) {
transferFromInternal(
assetMetadata[i],
from[i],
to[i],
amounts[i]
);
}
}
}

View File

@@ -1,120 +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.4.24;
pragma experimental ABIEncoderV2;
import "./mixins/MAuthorizable.sol";
import "../../utils/Ownable/Ownable.sol";
contract MixinAuthorizable is
Ownable,
MAuthorizable
{
// Revert reasons
string constant SENDER_NOT_AUTHORIZED = "Sender not authorized to call this method.";
string constant TARGET_NOT_AUTHORIZED = "Target address must be authorized.";
string constant TARGET_ALREADY_AUTHORIZED = "Target must not already be authorized.";
string constant INDEX_OUT_OF_BOUNDS = "Specified array index is out of bounds.";
string constant INDEX_ADDRESS_MISMATCH = "Address found at index does not match target address.";
/// @dev Only authorized addresses can invoke functions with this modifier.
modifier onlyAuthorized {
require(
authorized[msg.sender],
SENDER_NOT_AUTHORIZED
);
_;
}
mapping (address => bool) public authorized;
address[] public authorities;
/// @dev Authorizes an address.
/// @param target Address to authorize.
function addAuthorizedAddress(address target)
external
onlyOwner
{
require(
!authorized[target],
TARGET_ALREADY_AUTHORIZED
);
authorized[target] = true;
authorities.push(target);
emit AuthorizedAddressAdded(target, msg.sender);
}
/// @dev Removes authorizion of an address.
/// @param target Address to remove authorization from.
function removeAuthorizedAddress(address target)
external
onlyOwner
{
require(
authorized[target],
TARGET_NOT_AUTHORIZED
);
delete authorized[target];
for (uint i = 0; i < authorities.length; i++) {
if (authorities[i] == target) {
authorities[i] = authorities[authorities.length - 1];
authorities.length -= 1;
break;
}
}
emit AuthorizedAddressRemoved(target, msg.sender);
}
/// @dev Removes authorizion of an address.
/// @param target Address to remove authorization from.
/// @param index Index of target in authorities array.
function removeAuthorizedAddressAtIndex(
address target,
uint256 index
)
external
{
require(
index < authorities.length,
INDEX_OUT_OF_BOUNDS
);
require(
authorities[index] == target,
INDEX_ADDRESS_MISMATCH
);
delete authorized[target];
authorities[index] = authorities[authorities.length - 1];
authorities.length -= 1;
emit AuthorizedAddressRemoved(target, msg.sender);
}
/// @dev Gets all authorized addresses.
/// @return Array of authorized addresses.
function getAuthorizedAddresses()
external
view
returns (address[] memory)
{
return authorities;
}
}

View File

@@ -1,61 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;
import "./IAuthorizable.sol";
contract IAssetProxy is
IAuthorizable
{
/// @dev Transfers assets. Either succeeds or throws.
/// @param assetMetadata Byte array encoded for the respective asset proxy.
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
function transferFrom(
bytes assetMetadata,
address from,
address to,
uint256 amount
)
external;
/// @dev Makes multiple transfers of assets. Either succeeds or throws.
/// @param assetMetadata Array of byte arrays encoded for the respective asset proxy.
/// @param from Array of addresses to transfer assets from.
/// @param to Array of addresses to transfer assets to.
/// @param amounts Array of amounts of assets to transfer.
function batchTransferFrom(
bytes[] memory assetMetadata,
address[] memory from,
address[] memory to,
uint256[] memory amounts
)
public;
/// @dev Gets the proxy id associated with the proxy address.
/// @return Proxy id.
function getProxyId()
external
view
returns (uint8);
}

View File

@@ -1,53 +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.4.24;
pragma experimental ABIEncoderV2;
import "../../../utils/Ownable/IOwnable.sol";
contract IAuthorizable is
IOwnable
{
/// @dev Gets all authorized addresses.
/// @return Array of authorized addresses.
function getAuthorizedAddresses()
external
view
returns (address[]);
/// @dev Authorizes an address.
/// @param target Address to authorize.
function addAuthorizedAddress(address target)
external;
/// @dev Removes authorizion of an address.
/// @param target Address to remove authorization from.
function removeAuthorizedAddress(address target)
external;
/// @dev Removes authorizion of an address.
/// @param target Address to remove authorization from.
/// @param index Index of target in authorities array.
function removeAuthorizedAddressAtIndex(
address target,
uint256 index
)
external;
}

View File

@@ -1,40 +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.4.24;
pragma experimental ABIEncoderV2;
import "../interfaces/IAssetProxy.sol";
contract MAssetProxy is
IAssetProxy
{
/// @dev Internal version of `transferFrom`.
/// @param assetMetadata Encoded byte array.
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
function transferFromInternal(
bytes memory assetMetadata,
address from,
address to,
uint256 amount
)
internal;
}

View File

@@ -1,42 +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.4.24;
pragma experimental ABIEncoderV2;
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

@@ -1,111 +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.4.10;
import "../../multisig/MultiSigWalletWithTimeLock.sol";
import "../../utils/LibBytes/LibBytes.sol";
contract AssetProxyOwner is
LibBytes,
MultiSigWalletWithTimeLock
{
event AssetProxyRegistration(address assetProxyContract, bool isRegistered);
// Mapping of AssetProxy contract address =>
// if this contract is allowed to call the AssetProxy's removeAuthorizedAddress method without a time lock.
mapping (address => bool) public isAssetProxyRegistered;
bytes4 constant REMOVE_AUTHORIZED_ADDRESS_SELECTOR = bytes4(keccak256("removeAuthorizedAddress(address)"));
/// @dev Function will revert if the transaction does not call `removeAuthorizedAddress`
/// on an approved AssetProxy contract.
modifier validRemoveAuthorizedAddressTx(uint256 transactionId) {
Transaction storage tx = transactions[transactionId];
require(isAssetProxyRegistered[tx.destination]);
require(isFunctionRemoveAuthorizedAddress(tx.data));
_;
}
/// @dev Contract constructor sets initial owners, required number of confirmations,
/// time lock, and list of AssetProxy addresses.
/// @param _owners List of initial owners.
/// @param _assetProxyContracts Array of AssetProxy contract addresses.
/// @param _required Number of required confirmations.
/// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds.
function AssetProxyOwner(
address[] memory _owners,
address[] memory _assetProxyContracts,
uint256 _required,
uint256 _secondsTimeLocked
)
public
MultiSigWalletWithTimeLock(_owners, _required, _secondsTimeLocked)
{
for (uint256 i = 0; i < _assetProxyContracts.length; i++) {
address assetProxy = _assetProxyContracts[i];
require(assetProxy != address(0));
isAssetProxyRegistered[assetProxy] = true;
}
}
/// @dev Registers or deregisters an AssetProxy to be able to execute
/// removeAuthorizedAddress without a timelock.
/// @param assetProxyContract Address of AssetProxy contract.
/// @param isRegistered Status of approval for AssetProxy contract.
function registerAssetProxy(address assetProxyContract, bool isRegistered)
public
onlyWallet
notNull(assetProxyContract)
{
isAssetProxyRegistered[assetProxyContract] = isRegistered;
AssetProxyRegistration(assetProxyContract, isRegistered);
}
/// @dev Allows execution of removeAuthorizedAddress without time lock.
/// @param transactionId Transaction ID.
function executeRemoveAuthorizedAddress(uint256 transactionId)
public
notExecuted(transactionId)
fullyConfirmed(transactionId)
validRemoveAuthorizedAddressTx(transactionId)
{
Transaction storage tx = transactions[transactionId];
tx.executed = true;
if (tx.destination.call.value(tx.value)(tx.data))
Execution(transactionId);
else {
ExecutionFailure(transactionId);
tx.executed = false;
}
}
/// @dev Compares first 4 bytes of byte array to removeAuthorizedAddress function selector.
/// @param data Transaction data.
/// @return Successful if data is a call to removeAuthorizedAddress.
function isFunctionRemoveAuthorizedAddress(bytes memory data)
public
pure
returns (bool)
{
bytes4 first4Bytes = readFirst4(data);
require(REMOVE_AUTHORIZED_ADDRESS_SELECTOR == first4Bytes);
return true;
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
Copyright 2017 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,587 @@
*/
pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;
pragma solidity ^0.4.14;
import "./MixinExchangeCore.sol";
import "./MixinSignatureValidator.sol";
import "./MixinSettlement.sol";
import "./MixinWrapperFunctions.sol";
import "./MixinAssetProxyDispatcher.sol";
import "./MixinTransactions.sol";
import "./MixinMatchOrders.sol";
import { TokenTransferProxy } from "../TokenTransferProxy/TokenTransferProxy.sol";
import { Token_v1 as Token } from "../../../previous/Token/Token_v1.sol";
import { SafeMath_v1 as SafeMath } from "../../../previous/SafeMath/SafeMath_v1.sol";
contract Exchange is
MixinExchangeCore,
MixinMatchOrders,
MixinSettlement,
MixinSignatureValidator,
MixinTransactions,
MixinAssetProxyDispatcher,
MixinWrapperFunctions
{
/// @title Exchange - Facilitates exchange of ERC20 tokens.
/// @author Amir Bandeali - <amir@0xProject.com>, Will Warren - <will@0xProject.com>
contract Exchange is SafeMath {
string constant public VERSION = "2.0.1-alpha";
// Error Codes
enum Errors {
ORDER_EXPIRED, // Order has already expired
ORDER_FULLY_FILLED_OR_CANCELLED, // Order has already been fully filled or cancelled
ROUNDING_ERROR_TOO_LARGE, // Rounding error too large
INSUFFICIENT_BALANCE_OR_ALLOWANCE // Insufficient balance or allowance for token transfer
}
// Mixins are instantiated in the order they are inherited
constructor (bytes memory _zrxProxyData)
string constant public VERSION = "1.0.0";
uint16 constant public EXTERNAL_QUERY_GAS_LIMIT = 4999; // Changes to state require at least 5000 gas
address public ZRX_TOKEN_CONTRACT;
address public TOKEN_TRANSFER_PROXY_CONTRACT;
// Mappings of orderHash => amounts of takerTokenAmount filled or cancelled.
mapping (bytes32 => uint) public filled;
mapping (bytes32 => uint) public cancelled;
event LogFill(
address indexed maker,
address taker,
address indexed feeRecipient,
address makerToken,
address takerToken,
uint filledMakerTokenAmount,
uint filledTakerTokenAmount,
uint paidMakerFee,
uint paidTakerFee,
bytes32 indexed tokens, // keccak256(makerToken, takerToken), allows subscribing to a token pair
bytes32 orderHash
);
event LogCancel(
address indexed maker,
address indexed feeRecipient,
address makerToken,
address takerToken,
uint cancelledMakerTokenAmount,
uint cancelledTakerTokenAmount,
bytes32 indexed tokens,
bytes32 orderHash
);
event LogError(uint8 indexed errorId, bytes32 indexed orderHash);
struct Order {
address maker;
address taker;
address makerToken;
address takerToken;
address feeRecipient;
uint makerTokenAmount;
uint takerTokenAmount;
uint makerFee;
uint takerFee;
uint expirationTimestampInSec;
bytes32 orderHash;
}
function Exchange(address _zrxToken, address _tokenTransferProxy) {
ZRX_TOKEN_CONTRACT = _zrxToken;
TOKEN_TRANSFER_PROXY_CONTRACT = _tokenTransferProxy;
}
/*
* Core exchange functions
*/
/// @dev Fills the input order.
/// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient.
/// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @param fillTakerTokenAmount Desired amount of takerToken to fill.
/// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfer will fail before attempting.
/// @param v ECDSA signature parameter v.
/// @param r ECDSA signature parameters r.
/// @param s ECDSA signature parameters s.
/// @return Total amount of takerToken filled in trade.
function fillOrder(
address[5] orderAddresses,
uint[6] orderValues,
uint fillTakerTokenAmount,
bool shouldThrowOnInsufficientBalanceOrAllowance,
uint8 v,
bytes32 r,
bytes32 s)
public
returns (uint filledTakerTokenAmount)
{
Order memory order = Order({
maker: orderAddresses[0],
taker: orderAddresses[1],
makerToken: orderAddresses[2],
takerToken: orderAddresses[3],
feeRecipient: orderAddresses[4],
makerTokenAmount: orderValues[0],
takerTokenAmount: orderValues[1],
makerFee: orderValues[2],
takerFee: orderValues[3],
expirationTimestampInSec: orderValues[4],
orderHash: getOrderHash(orderAddresses, orderValues)
});
require(order.taker == address(0) || order.taker == msg.sender);
require(order.makerTokenAmount > 0 && order.takerTokenAmount > 0 && fillTakerTokenAmount > 0);
require(isValidSignature(
order.maker,
order.orderHash,
v,
r,
s
));
if (block.timestamp >= order.expirationTimestampInSec) {
LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash);
return 0;
}
uint remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(order.orderHash));
filledTakerTokenAmount = min256(fillTakerTokenAmount, remainingTakerTokenAmount);
if (filledTakerTokenAmount == 0) {
LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), order.orderHash);
return 0;
}
if (isRoundingError(filledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount)) {
LogError(uint8(Errors.ROUNDING_ERROR_TOO_LARGE), order.orderHash);
return 0;
}
if (!shouldThrowOnInsufficientBalanceOrAllowance && !isTransferable(order, filledTakerTokenAmount)) {
LogError(uint8(Errors.INSUFFICIENT_BALANCE_OR_ALLOWANCE), order.orderHash);
return 0;
}
uint filledMakerTokenAmount = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount);
uint paidMakerFee;
uint paidTakerFee;
filled[order.orderHash] = safeAdd(filled[order.orderHash], filledTakerTokenAmount);
require(transferViaTokenTransferProxy(
order.makerToken,
order.maker,
msg.sender,
filledMakerTokenAmount
));
require(transferViaTokenTransferProxy(
order.takerToken,
msg.sender,
order.maker,
filledTakerTokenAmount
));
if (order.feeRecipient != address(0)) {
if (order.makerFee > 0) {
paidMakerFee = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.makerFee);
require(transferViaTokenTransferProxy(
ZRX_TOKEN_CONTRACT,
order.maker,
order.feeRecipient,
paidMakerFee
));
}
if (order.takerFee > 0) {
paidTakerFee = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.takerFee);
require(transferViaTokenTransferProxy(
ZRX_TOKEN_CONTRACT,
msg.sender,
order.feeRecipient,
paidTakerFee
));
}
}
LogFill(
order.maker,
msg.sender,
order.feeRecipient,
order.makerToken,
order.takerToken,
filledMakerTokenAmount,
filledTakerTokenAmount,
paidMakerFee,
paidTakerFee,
keccak256(order.makerToken, order.takerToken),
order.orderHash
);
return filledTakerTokenAmount;
}
/// @dev Cancels the input order.
/// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient.
/// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @param cancelTakerTokenAmount Desired amount of takerToken to cancel in order.
/// @return Amount of takerToken cancelled.
function cancelOrder(
address[5] orderAddresses,
uint[6] orderValues,
uint cancelTakerTokenAmount)
public
MixinExchangeCore()
MixinMatchOrders()
MixinSettlement(_zrxProxyData)
MixinSignatureValidator()
MixinTransactions()
MixinAssetProxyDispatcher()
MixinWrapperFunctions()
{}
returns (uint)
{
Order memory order = Order({
maker: orderAddresses[0],
taker: orderAddresses[1],
makerToken: orderAddresses[2],
takerToken: orderAddresses[3],
feeRecipient: orderAddresses[4],
makerTokenAmount: orderValues[0],
takerTokenAmount: orderValues[1],
makerFee: orderValues[2],
takerFee: orderValues[3],
expirationTimestampInSec: orderValues[4],
orderHash: getOrderHash(orderAddresses, orderValues)
});
require(order.maker == msg.sender);
require(order.makerTokenAmount > 0 && order.takerTokenAmount > 0 && cancelTakerTokenAmount > 0);
if (block.timestamp >= order.expirationTimestampInSec) {
LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash);
return 0;
}
uint remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(order.orderHash));
uint cancelledTakerTokenAmount = min256(cancelTakerTokenAmount, remainingTakerTokenAmount);
if (cancelledTakerTokenAmount == 0) {
LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), order.orderHash);
return 0;
}
cancelled[order.orderHash] = safeAdd(cancelled[order.orderHash], cancelledTakerTokenAmount);
LogCancel(
order.maker,
order.feeRecipient,
order.makerToken,
order.takerToken,
getPartialAmount(cancelledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount),
cancelledTakerTokenAmount,
keccak256(order.makerToken, order.takerToken),
order.orderHash
);
return cancelledTakerTokenAmount;
}
/*
* Wrapper functions
*/
/// @dev Fills an order with specified parameters and ECDSA signature, throws if specified amount not filled entirely.
/// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient.
/// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @param fillTakerTokenAmount Desired amount of takerToken to fill.
/// @param v ECDSA signature parameter v.
/// @param r ECDSA signature parameters r.
/// @param s ECDSA signature parameters s.
function fillOrKillOrder(
address[5] orderAddresses,
uint[6] orderValues,
uint fillTakerTokenAmount,
uint8 v,
bytes32 r,
bytes32 s)
public
{
require(fillOrder(
orderAddresses,
orderValues,
fillTakerTokenAmount,
false,
v,
r,
s
) == fillTakerTokenAmount);
}
/// @dev Synchronously executes multiple fill orders in a single transaction.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint arrays containing individual order values.
/// @param fillTakerTokenAmounts Array of desired amounts of takerToken to fill in orders.
/// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfers will fail before attempting.
/// @param v Array ECDSA signature v parameters.
/// @param r Array of ECDSA signature r parameters.
/// @param s Array of ECDSA signature s parameters.
function batchFillOrders(
address[5][] orderAddresses,
uint[6][] orderValues,
uint[] fillTakerTokenAmounts,
bool shouldThrowOnInsufficientBalanceOrAllowance,
uint8[] v,
bytes32[] r,
bytes32[] s)
public
{
for (uint i = 0; i < orderAddresses.length; i++) {
fillOrder(
orderAddresses[i],
orderValues[i],
fillTakerTokenAmounts[i],
shouldThrowOnInsufficientBalanceOrAllowance,
v[i],
r[i],
s[i]
);
}
}
/// @dev Synchronously executes multiple fillOrKill orders in a single transaction.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint arrays containing individual order values.
/// @param fillTakerTokenAmounts Array of desired amounts of takerToken to fill in orders.
/// @param v Array ECDSA signature v parameters.
/// @param r Array of ECDSA signature r parameters.
/// @param s Array of ECDSA signature s parameters.
function batchFillOrKillOrders(
address[5][] orderAddresses,
uint[6][] orderValues,
uint[] fillTakerTokenAmounts,
uint8[] v,
bytes32[] r,
bytes32[] s)
public
{
for (uint i = 0; i < orderAddresses.length; i++) {
fillOrKillOrder(
orderAddresses[i],
orderValues[i],
fillTakerTokenAmounts[i],
v[i],
r[i],
s[i]
);
}
}
/// @dev Synchronously executes multiple fill orders in a single transaction until total fillTakerTokenAmount filled.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint arrays containing individual order values.
/// @param fillTakerTokenAmount Desired total amount of takerToken to fill in orders.
/// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfers will fail before attempting.
/// @param v Array ECDSA signature v parameters.
/// @param r Array of ECDSA signature r parameters.
/// @param s Array of ECDSA signature s parameters.
/// @return Total amount of fillTakerTokenAmount filled in orders.
function fillOrdersUpTo(
address[5][] orderAddresses,
uint[6][] orderValues,
uint fillTakerTokenAmount,
bool shouldThrowOnInsufficientBalanceOrAllowance,
uint8[] v,
bytes32[] r,
bytes32[] s)
public
returns (uint)
{
uint filledTakerTokenAmount = 0;
for (uint i = 0; i < orderAddresses.length; i++) {
require(orderAddresses[i][3] == orderAddresses[0][3]); // takerToken must be the same for each order
filledTakerTokenAmount = safeAdd(filledTakerTokenAmount, fillOrder(
orderAddresses[i],
orderValues[i],
safeSub(fillTakerTokenAmount, filledTakerTokenAmount),
shouldThrowOnInsufficientBalanceOrAllowance,
v[i],
r[i],
s[i]
));
if (filledTakerTokenAmount == fillTakerTokenAmount) break;
}
return filledTakerTokenAmount;
}
/// @dev Synchronously cancels multiple orders in a single transaction.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint arrays containing individual order values.
/// @param cancelTakerTokenAmounts Array of desired amounts of takerToken to cancel in orders.
function batchCancelOrders(
address[5][] orderAddresses,
uint[6][] orderValues,
uint[] cancelTakerTokenAmounts)
public
{
for (uint i = 0; i < orderAddresses.length; i++) {
cancelOrder(
orderAddresses[i],
orderValues[i],
cancelTakerTokenAmounts[i]
);
}
}
/*
* Constant public functions
*/
/// @dev Calculates Keccak-256 hash of order with specified parameters.
/// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient.
/// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @return Keccak-256 hash of order.
function getOrderHash(address[5] orderAddresses, uint[6] orderValues)
public
constant
returns (bytes32)
{
return keccak256(
address(this),
orderAddresses[0], // maker
orderAddresses[1], // taker
orderAddresses[2], // makerToken
orderAddresses[3], // takerToken
orderAddresses[4], // feeRecipient
orderValues[0], // makerTokenAmount
orderValues[1], // takerTokenAmount
orderValues[2], // makerFee
orderValues[3], // takerFee
orderValues[4], // expirationTimestampInSec
orderValues[5] // salt
);
}
/// @dev Verifies that an order signature is valid.
/// @param signer address of signer.
/// @param hash Signed Keccak-256 hash.
/// @param v ECDSA signature parameter v.
/// @param r ECDSA signature parameters r.
/// @param s ECDSA signature parameters s.
/// @return Validity of order signature.
function isValidSignature(
address signer,
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s)
public
constant
returns (bool)
{
return signer == ecrecover(
keccak256("\x19Ethereum Signed Message:\n32", hash),
v,
r,
s
);
}
/// @dev Checks if rounding error > 0.1%.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator.
/// @return Rounding error is present.
function isRoundingError(uint numerator, uint denominator, uint target)
public
constant
returns (bool)
{
uint remainder = mulmod(target, numerator, denominator);
if (remainder == 0) return false; // No rounding error.
uint errPercentageTimes1000000 = safeDiv(
safeMul(remainder, 1000000),
safeMul(numerator, target)
);
return errPercentageTimes1000000 > 1000;
}
/// @dev Calculates partial value given a numerator and denominator.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to calculate partial of.
/// @return Partial value of target.
function getPartialAmount(uint numerator, uint denominator, uint target)
public
constant
returns (uint)
{
return safeDiv(safeMul(numerator, target), denominator);
}
/// @dev Calculates the sum of values already filled and cancelled for a given order.
/// @param orderHash The Keccak-256 hash of the given order.
/// @return Sum of values already filled and cancelled.
function getUnavailableTakerTokenAmount(bytes32 orderHash)
public
constant
returns (uint)
{
return safeAdd(filled[orderHash], cancelled[orderHash]);
}
/*
* Internal functions
*/
/// @dev Transfers a token using TokenTransferProxy transferFrom function.
/// @param token Address of token to transferFrom.
/// @param from Address transfering token.
/// @param to Address receiving token.
/// @param value Amount of token to transfer.
/// @return Success of token transfer.
function transferViaTokenTransferProxy(
address token,
address from,
address to,
uint value)
internal
returns (bool)
{
return TokenTransferProxy(TOKEN_TRANSFER_PROXY_CONTRACT).transferFrom(token, from, to, value);
}
/// @dev Checks if any order transfers will fail.
/// @param order Order struct of params that will be checked.
/// @param fillTakerTokenAmount Desired amount of takerToken to fill.
/// @return Predicted result of transfers.
function isTransferable(Order order, uint fillTakerTokenAmount)
internal
constant // The called token contracts may attempt to change state, but will not be able to due to gas limits on getBalance and getAllowance.
returns (bool)
{
address taker = msg.sender;
uint fillMakerTokenAmount = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount);
if (order.feeRecipient != address(0)) {
bool isMakerTokenZRX = order.makerToken == ZRX_TOKEN_CONTRACT;
bool isTakerTokenZRX = order.takerToken == ZRX_TOKEN_CONTRACT;
uint paidMakerFee = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.makerFee);
uint paidTakerFee = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.takerFee);
uint requiredMakerZRX = isMakerTokenZRX ? safeAdd(fillMakerTokenAmount, paidMakerFee) : paidMakerFee;
uint requiredTakerZRX = isTakerTokenZRX ? safeAdd(fillTakerTokenAmount, paidTakerFee) : paidTakerFee;
if ( getBalance(ZRX_TOKEN_CONTRACT, order.maker) < requiredMakerZRX
|| getAllowance(ZRX_TOKEN_CONTRACT, order.maker) < requiredMakerZRX
|| getBalance(ZRX_TOKEN_CONTRACT, taker) < requiredTakerZRX
|| getAllowance(ZRX_TOKEN_CONTRACT, taker) < requiredTakerZRX
) return false;
if (!isMakerTokenZRX && ( getBalance(order.makerToken, order.maker) < fillMakerTokenAmount // Don't double check makerToken if ZRX
|| getAllowance(order.makerToken, order.maker) < fillMakerTokenAmount)
) return false;
if (!isTakerTokenZRX && ( getBalance(order.takerToken, taker) < fillTakerTokenAmount // Don't double check takerToken if ZRX
|| getAllowance(order.takerToken, taker) < fillTakerTokenAmount)
) return false;
} else if ( getBalance(order.makerToken, order.maker) < fillMakerTokenAmount
|| getAllowance(order.makerToken, order.maker) < fillMakerTokenAmount
|| getBalance(order.takerToken, taker) < fillTakerTokenAmount
|| getAllowance(order.takerToken, taker) < fillTakerTokenAmount
) return false;
return true;
}
/// @dev Get token balance of an address.
/// @param token Address of token.
/// @param owner Address of owner.
/// @return Token balance of owner.
function getBalance(address token, address owner)
internal
constant // The called token contract may attempt to change state, but will not be able to due to an added gas limit.
returns (uint)
{
return Token(token).balanceOf.gas(EXTERNAL_QUERY_GAS_LIMIT)(owner); // Limit gas to prevent reentrancy
}
/// @dev Get allowance of token given to TokenTransferProxy by an address.
/// @param token Address of token.
/// @param owner Address of owner.
/// @return Allowance of token given to TokenTransferProxy by owner.
function getAllowance(address token, address owner)
internal
constant // The called token contract may attempt to change state, but will not be able to due to an added gas limit.
returns (uint)
{
return Token(token).allowance.gas(EXTERNAL_QUERY_GAS_LIMIT)(owner, TOKEN_TRANSFER_PROXY_CONTRACT); // Limit gas to prevent reentrancy
}
}

View File

@@ -1,110 +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.4.24;
import "../../utils/Ownable/Ownable.sol";
import "../AssetProxy/interfaces/IAssetProxy.sol";
import "./libs/LibExchangeErrors.sol";
import "./mixins/MAssetProxyDispatcher.sol";
contract MixinAssetProxyDispatcher is
LibExchangeErrors,
Ownable,
MAssetProxyDispatcher
{
// Mapping from Asset Proxy Id's to their respective Asset Proxy
mapping (uint8 => IAssetProxy) public assetProxies;
/// @dev Registers an asset proxy to an asset proxy id.
/// An id can only be assigned to a single proxy at a given time.
/// @param assetProxyId Id to register`newAssetProxy` under.
/// @param newAssetProxy Address of new asset proxy to register, or 0x0 to unset assetProxyId.
/// @param oldAssetProxy Existing asset proxy to overwrite, or 0x0 if assetProxyId is currently unused.
function registerAssetProxy(
uint8 assetProxyId,
address newAssetProxy,
address oldAssetProxy
)
external
onlyOwner
{
// Ensure the existing asset proxy is not unintentionally overwritten
require(
oldAssetProxy == address(assetProxies[assetProxyId]),
OLD_ASSET_PROXY_MISMATCH
);
IAssetProxy assetProxy = IAssetProxy(newAssetProxy);
// Ensure that the id of newAssetProxy matches the passed in assetProxyId, unless it is being reset to 0.
if (newAssetProxy != address(0)) {
uint8 newAssetProxyId = assetProxy.getProxyId();
require(
newAssetProxyId == assetProxyId,
NEW_ASSET_PROXY_MISMATCH
);
}
// Add asset proxy and log registration.
assetProxies[assetProxyId] = assetProxy;
emit AssetProxySet(assetProxyId, newAssetProxy, oldAssetProxy);
}
/// @dev Gets an asset proxy.
/// @param assetProxyId Id of the asset proxy.
/// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.
function getAssetProxy(uint8 assetProxyId)
external
view
returns (address)
{
address assetProxy = address(assetProxies[assetProxyId]);
return assetProxy;
}
/// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.
/// @param assetMetadata Byte array encoded for the respective asset proxy.
/// @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 assetMetadata,
address from,
address to,
uint256 amount
)
internal
{
// Do nothing if no amount should be transferred.
if (amount > 0) {
// Lookup asset proxy
uint256 length = assetMetadata.length;
require(
length > 0,
GT_ZERO_LENGTH_REQUIRED
);
uint8 assetProxyId = uint8(assetMetadata[length - 1]);
IAssetProxy assetProxy = assetProxies[assetProxyId];
// transferFrom will either succeed or throw.
assetProxy.transferFrom(assetMetadata, from, to, amount);
}
}
}

View File

@@ -1,446 +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.4.24;
pragma experimental ABIEncoderV2;
import "./libs/LibFillResults.sol";
import "./libs/LibOrder.sol";
import "./libs/LibMath.sol";
import "./libs/LibStatus.sol";
import "./libs/LibExchangeErrors.sol";
import "./mixins/MExchangeCore.sol";
import "./mixins/MSettlement.sol";
import "./mixins/MSignatureValidator.sol";
import "./mixins/MTransactions.sol";
contract MixinExchangeCore is
SafeMath,
LibMath,
LibStatus,
LibOrder,
LibFillResults,
LibExchangeErrors,
MExchangeCore,
MSettlement,
MSignatureValidator,
MTransactions
{
// Mapping of orderHash => amount of takerAsset already bought by maker
mapping (bytes32 => uint256) public filled;
// Mapping of orderHash => cancelled
mapping (bytes32 => bool) public cancelled;
// Mapping of makerAddress => lowest salt an order can have in order to be fillable
// Orders with a salt less than their maker's epoch are considered cancelled
mapping (address => uint256) public makerEpoch;
////// Core exchange functions //////
/// @dev Cancels all orders reated by sender with a salt less than or equal to the specified salt value.
/// @param salt Orders created with a salt less or equal to this value will be cancelled.
function cancelOrdersUpTo(uint256 salt)
external
{
uint256 newMakerEpoch = salt + 1; // makerEpoch is initialized to 0, so to cancelUpTo we need salt + 1
require(
newMakerEpoch > makerEpoch[msg.sender], // epoch must be monotonically increasing
INVALID_NEW_MAKER_EPOCH
);
makerEpoch[msg.sender] = newMakerEpoch;
emit CancelUpTo(msg.sender, newMakerEpoch);
}
/// @dev Fills the input order.
/// @param order Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
/// @return Amounts filled and fees paid by maker and taker.
function fillOrder(
Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature
)
public
returns (FillResults memory fillResults)
{
// Fetch order info
OrderInfo memory orderInfo = getOrderInfo(order);
// Fetch taker address
address takerAddress = getCurrentContextAddress();
// Either our context is valid or we revert
assertValidFill(
order,
orderInfo.orderStatus,
orderInfo.orderHash,
takerAddress,
orderInfo.orderTakerAssetFilledAmount,
takerAssetFillAmount,
signature
);
// Compute proportional fill amounts
uint8 status;
(status, fillResults) = calculateFillResults(
order,
orderInfo.orderStatus,
orderInfo.orderTakerAssetFilledAmount,
takerAssetFillAmount
);
if (status != uint8(Status.SUCCESS)) {
emit ExchangeStatus(uint8(status), orderInfo.orderHash);
return getNullFillResults();
}
// Settle order
settleOrder(order, takerAddress, fillResults);
// Update exchange internal state
updateFilledState(
order,
takerAddress,
orderInfo.orderHash,
orderInfo.orderTakerAssetFilledAmount,
fillResults
);
return fillResults;
}
/// @dev After calling, the order can not be filled anymore.
/// Throws if order is invalid or sender does not have permission to cancel.
/// @param order Order to cancel. Order must be Status.FILLABLE.
/// @return True if the order state changed to cancelled.
/// False if the order was valid, but in an
/// unfillable state (see LibStatus.STATUS for order states)
function cancelOrder(Order memory order)
public
returns (bool)
{
// Fetch current order status
OrderInfo memory orderInfo = getOrderInfo(order);
// Validate context
assertValidCancel(order, orderInfo.orderStatus, orderInfo.orderHash);
// Perform cancel
return updateCancelledState(order, orderInfo.orderStatus, orderInfo.orderHash);
}
/// @dev Gets information about an order: status, hash, and amount filled.
/// @param order Order to gather information on.
/// @return OrderInfo Information about the order and its state.
/// See LibOrder.OrderInfo for a complete description.
function getOrderInfo(Order memory order)
public
view
returns (LibOrder.OrderInfo memory orderInfo)
{
// Compute the order hash
orderInfo.orderHash = getOrderHash(order);
// If order.makerAssetAmount is zero, we also reject the order.
// While the Exchange contract handles them correctly, they create
// edge cases in the supporting infrastructure because they have
// an 'infinite' price when computed by a simple division.
if (order.makerAssetAmount == 0) {
orderInfo.orderStatus = uint8(Status.ORDER_INVALID_MAKER_ASSET_AMOUNT);
return orderInfo;
}
// If order.takerAssetAmount is zero, then the order will always
// be considered filled because 0 == takerAssetAmount == orderTakerAssetFilledAmount
// Instead of distinguishing between unfilled and filled zero taker
// amount orders, we choose not to support them.
if (order.takerAssetAmount == 0) {
orderInfo.orderStatus = uint8(Status.ORDER_INVALID_TAKER_ASSET_AMOUNT);
return orderInfo;
}
// Validate order expiration
if (block.timestamp >= order.expirationTimeSeconds) {
orderInfo.orderStatus = uint8(Status.ORDER_EXPIRED);
return orderInfo;
}
// Check if order has been cancelled
if (cancelled[orderInfo.orderHash]) {
orderInfo.orderStatus = uint8(Status.ORDER_CANCELLED);
return orderInfo;
}
if (makerEpoch[order.makerAddress] > order.salt) {
orderInfo.orderStatus = uint8(Status.ORDER_CANCELLED);
return orderInfo;
}
// Fetch filled amount and validate order availability
orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash];
if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) {
orderInfo.orderStatus = uint8(Status.ORDER_FULLY_FILLED);
return orderInfo;
}
// All other statuses are ruled out: order is Fillable
orderInfo.orderStatus = uint8(Status.ORDER_FILLABLE);
return orderInfo;
}
/// @dev Calculates amounts filled and fees paid by maker and taker.
/// @param order to be filled.
/// @param orderStatus Status of order to be filled.
/// @param orderTakerAssetFilledAmount Amount of order already filled.
/// @param takerAssetFillAmount Desired amount of order to fill by taker.
/// @return status Return status of calculating fill amounts. Returns Status.SUCCESS on success.
/// @return fillResults Amounts filled and fees paid by maker and taker.
function calculateFillResults(
Order memory order,
uint8 orderStatus,
uint256 orderTakerAssetFilledAmount,
uint256 takerAssetFillAmount
)
public
pure
returns (
uint8 status,
FillResults memory fillResults
)
{
// Fill amount must be greater than 0
if (takerAssetFillAmount == 0) {
status = uint8(Status.TAKER_ASSET_FILL_AMOUNT_TOO_LOW);
return (status, fillResults);
}
// Ensure the order is fillable
if (orderStatus != uint8(Status.ORDER_FILLABLE)) {
status = orderStatus;
return (status, fillResults);
}
// Compute takerAssetFilledAmount
uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderTakerAssetFilledAmount);
uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount);
// Validate fill order rounding
if (isRoundingError(
takerAssetFilledAmount,
order.takerAssetAmount,
order.makerAssetAmount))
{
status = uint8(Status.ROUNDING_ERROR_TOO_LARGE);
return (status, fillResults);
}
// Compute proportional transfer amounts
// TODO: All three are multiplied by the same fraction. This can
// potentially be optimized.
fillResults.takerAssetFilledAmount = takerAssetFilledAmount;
fillResults.makerAssetFilledAmount = getPartialAmount(
fillResults.takerAssetFilledAmount,
order.takerAssetAmount,
order.makerAssetAmount
);
fillResults.makerFeePaid = getPartialAmount(
fillResults.takerAssetFilledAmount,
order.takerAssetAmount,
order.makerFee
);
fillResults.takerFeePaid = getPartialAmount(
fillResults.takerAssetFilledAmount,
order.takerAssetAmount,
order.takerFee
);
status = uint8(Status.SUCCESS);
return (status, fillResults);
}
/// @dev Validates context for fillOrder. Succeeds or throws.
/// @param order to be filled.
/// @param orderStatus Status of order to be filled.
/// @param orderHash Hash of order to be filled.
/// @param takerAddress Address of order taker.
/// @param orderTakerAssetFilledAmount Amount of order already filled.
/// @param takerAssetFillAmount Desired amount of order to fill by taker.
/// @param signature Proof that the orders was created by its maker.
function assertValidFill(
Order memory order,
uint8 orderStatus,
bytes32 orderHash,
address takerAddress,
uint256 orderTakerAssetFilledAmount,
uint256 takerAssetFillAmount,
bytes memory signature
)
internal
{
// Ensure order is valid
// An order can only be filled if its status is FILLABLE;
// however, only invalid statuses result in a throw.
// See LibStatus for a complete description of order statuses.
require(
orderStatus != uint8(Status.ORDER_INVALID_MAKER_ASSET_AMOUNT),
INVALID_ORDER_MAKER_ASSET_AMOUNT
);
require(
orderStatus != uint8(Status.ORDER_INVALID_TAKER_ASSET_AMOUNT),
INVALID_ORDER_TAKER_ASSET_AMOUNT
);
// Validate Maker signature (check only if first time seen)
if (orderTakerAssetFilledAmount == 0) {
require(
isValidSignature(orderHash, order.makerAddress, signature),
SIGNATURE_VALIDATION_FAILED
);
}
// Validate sender is allowed to fill this order
if (order.senderAddress != address(0)) {
require(
order.senderAddress == msg.sender,
INVALID_SENDER
);
}
// Validate taker is allowed to fill this order
if (order.takerAddress != address(0)) {
require(
order.takerAddress == takerAddress,
INVALID_CONTEXT
);
}
require(
takerAssetFillAmount > 0,
GT_ZERO_AMOUNT_REQUIRED
);
}
/// @dev Updates state with results of a fill order.
/// @param order that was filled.
/// @param takerAddress Address of taker who filled the order.
/// @param orderTakerAssetFilledAmount Amount of order already filled.
/// @return fillResults Amounts filled and fees paid by maker and taker.
function updateFilledState(
Order memory order,
address takerAddress,
bytes32 orderHash,
uint256 orderTakerAssetFilledAmount,
FillResults memory fillResults
)
internal
{
// Update state
filled[orderHash] = safeAdd(orderTakerAssetFilledAmount, fillResults.takerAssetFilledAmount);
// Log order
emit Fill(
order.makerAddress,
takerAddress,
order.feeRecipientAddress,
fillResults.makerAssetFilledAmount,
fillResults.takerAssetFilledAmount,
fillResults.makerFeePaid,
fillResults.takerFeePaid,
orderHash,
order.makerAssetData,
order.takerAssetData
);
}
/// @dev Validates context for cancelOrder. Succeeds or throws.
/// @param order that was cancelled.
/// @param orderStatus Status of order that was cancelled.
/// @param orderHash Hash of order that was cancelled.
function assertValidCancel(
Order memory order,
uint8 orderStatus,
bytes32 orderHash
)
internal
{
// Ensure order is valid
// An order can only be cancelled if its status is FILLABLE;
// however, only invalid statuses result in a throw.
// See LibStatus for a complete description of order statuses.
require(
orderStatus != uint8(Status.ORDER_INVALID_MAKER_ASSET_AMOUNT),
INVALID_ORDER_MAKER_ASSET_AMOUNT
);
require(
orderStatus != uint8(Status.ORDER_INVALID_TAKER_ASSET_AMOUNT),
INVALID_ORDER_TAKER_ASSET_AMOUNT
);
// Validate transaction signed by maker
address makerAddress = getCurrentContextAddress();
require(
order.makerAddress == makerAddress,
INVALID_CONTEXT
);
// Validate sender is allowed to cancel this order
if (order.senderAddress != address(0)) {
require(
order.senderAddress == msg.sender,
INVALID_SENDER
);
}
}
/// @dev Updates state with results of cancelling an order.
/// State is only updated if the order is currently fillable.
/// Otherwise, updating state would have no effect.
/// @param order that was cancelled.
/// @param orderStatus Status of order that was cancelled.
/// @param orderHash Hash of order that was cancelled.
/// @return stateUpdated Returns true only if state was updated.
function updateCancelledState(
Order memory order,
uint8 orderStatus,
bytes32 orderHash
)
internal
returns (bool stateUpdated)
{
// Ensure order is fillable (otherwise cancelling does nothing)
// See LibStatus for a complete description of order statuses.
if (orderStatus != uint8(Status.ORDER_FILLABLE)) {
emit ExchangeStatus(uint8(orderStatus), orderHash);
stateUpdated = false;
return stateUpdated;
}
// Perform cancel
cancelled[orderHash] = true;
stateUpdated = true;
// Log cancel
emit Cancel(
order.makerAddress,
order.feeRecipientAddress,
orderHash,
order.makerAssetData,
order.takerAssetData
);
return stateUpdated;
}
}

View File

@@ -1,297 +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.4.24;
pragma experimental ABIEncoderV2;
import "./mixins/MExchangeCore.sol";
import "./mixins/MMatchOrders.sol";
import "./mixins/MSettlement.sol";
import "./mixins/MTransactions.sol";
import "../../utils/SafeMath/SafeMath.sol";
import "./libs/LibMath.sol";
import "./libs/LibOrder.sol";
import "./libs/LibStatus.sol";
import "../../utils/LibBytes/LibBytes.sol";
import "./libs/LibExchangeErrors.sol";
contract MixinMatchOrders is
SafeMath,
LibBytes,
LibMath,
LibStatus,
LibOrder,
LibFillResults,
LibExchangeErrors,
MExchangeCore,
MMatchOrders,
MSettlement,
MTransactions
{
/// @dev Match two complementary orders that have a profitable spread.
/// Each order is filled at their respective price point. However, the calculations are
/// carried out as though the orders are both being filled at the right order's price point.
/// The profit made by the left order goes to the taker (who matched the two orders).
/// @param leftOrder First order to match.
/// @param rightOrder Second order to match.
/// @param leftSignature Proof that order was created by the left maker.
/// @param rightSignature Proof that order was created by the right maker.
/// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders.
/// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)
function matchOrders(
Order memory leftOrder,
Order memory rightOrder,
bytes memory leftSignature,
bytes memory rightSignature
)
public
returns (MatchedFillResults memory matchedFillResults)
{
// Get left & right order info
OrderInfo memory leftOrderInfo = getOrderInfo(leftOrder);
OrderInfo memory rightOrderInfo = getOrderInfo(rightOrder);
// Fetch taker address
address takerAddress = getCurrentContextAddress();
// Either our context is valid or we revert
assertValidMatch(leftOrder, rightOrder);
// Compute proportional fill amounts
matchedFillResults = calculateMatchedFillResults(
leftOrder,
rightOrder,
leftOrderInfo.orderStatus,
rightOrderInfo.orderStatus,
leftOrderInfo.orderTakerAssetFilledAmount,
rightOrderInfo.orderTakerAssetFilledAmount
);
// Validate fill contexts
assertValidFill(
leftOrder,
leftOrderInfo.orderStatus,
leftOrderInfo.orderHash,
takerAddress,
leftOrderInfo.orderTakerAssetFilledAmount,
matchedFillResults.left.takerAssetFilledAmount,
leftSignature
);
assertValidFill(
rightOrder,
rightOrderInfo.orderStatus,
rightOrderInfo.orderHash,
takerAddress,
rightOrderInfo.orderTakerAssetFilledAmount,
matchedFillResults.right.takerAssetFilledAmount,
rightSignature
);
// Settle matched orders. Succeeds or throws.
settleMatchedOrders(
leftOrder,
rightOrder,
takerAddress,
matchedFillResults
);
// Update exchange state
updateFilledState(
leftOrder,
takerAddress,
leftOrderInfo.orderHash,
leftOrderInfo.orderTakerAssetFilledAmount,
matchedFillResults.left
);
updateFilledState(
rightOrder,
takerAddress,
rightOrderInfo.orderHash,
rightOrderInfo.orderTakerAssetFilledAmount,
matchedFillResults.right
);
return matchedFillResults;
}
/// @dev Validates context for matchOrders. Succeeds or throws.
/// @param leftOrder First order to match.
/// @param rightOrder Second order to match.
function assertValidMatch(
Order memory leftOrder,
Order memory rightOrder
)
internal
{
// The leftOrder maker asset must be the same as the rightOrder taker asset.
// TODO: Can we safely assume equality and expect a later failure otherwise?
require(
areBytesEqual(leftOrder.makerAssetData, rightOrder.takerAssetData),
ASSET_MISMATCH_MAKER_TAKER
);
// The leftOrder taker asset must be the same as the rightOrder maker asset.
// TODO: Can we safely assume equality and expect a later failure otherwise?
require(
areBytesEqual(leftOrder.takerAssetData, rightOrder.makerAssetData),
ASSET_MISMATCH_TAKER_MAKER
);
// Make sure there is a profitable spread.
// There is a profitable spread iff the cost per unit bought (OrderA.MakerAmount/OrderA.TakerAmount) for each order is greater
// than the profit per unit sold of the matched order (OrderB.TakerAmount/OrderB.MakerAmount).
// This is satisfied by the equations below:
// <leftOrder.makerAssetAmount> / <leftOrder.takerAssetAmount> >= <rightOrder.takerAssetAmount> / <rightOrder.makerAssetAmount>
// AND
// <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount> >= <leftOrder.takerAssetAmount> / <leftOrder.makerAssetAmount>
// These equations can be combined to get the following:
require(
safeMul(leftOrder.makerAssetAmount, rightOrder.makerAssetAmount) >=
safeMul(leftOrder.takerAssetAmount, rightOrder.takerAssetAmount),
NEGATIVE_SPREAD
);
}
/// @dev Validates matched fill results. Succeeds or throws.
/// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.
function assertValidMatchResults(MatchedFillResults memory matchedFillResults)
internal
{
// If the amount transferred from the left order is different than what is transferred, it is a rounding error amount.
// Ensure this difference is negligible by dividing the values with each other. The result should equal to ~1.
uint256 amountSpentByLeft = safeAdd(
matchedFillResults.right.takerAssetFilledAmount,
matchedFillResults.takerFillAmount
);
require(
!isRoundingError(
matchedFillResults.left.makerAssetFilledAmount,
amountSpentByLeft,
1
),
ROUNDING_ERROR_TRANSFER_AMOUNTS
);
// If the amount transferred from the right order is different than what is transferred, it is a rounding error amount.
// Ensure this difference is negligible by dividing the values with each other. The result should equal to ~1.
require(
!isRoundingError(
matchedFillResults.right.makerAssetFilledAmount,
matchedFillResults.left.takerAssetFilledAmount,
1
),
ROUNDING_ERROR_TRANSFER_AMOUNTS
);
}
/// @dev Calculates fill amounts for the matched orders.
/// Each order is filled at their respective price point. However, the calculations are
/// carried out as though the orders are both being filled at the right order's price point.
/// The profit made by the leftOrder order goes to the taker (who matched the two orders).
/// @param leftOrder First order to match.
/// @param rightOrder Second order to match.
/// @param leftOrderStatus Order status of left order.
/// @param rightOrderStatus Order status of right order.
/// @param leftOrderFilledAmount Amount of left order already filled.
/// @param rightOrderFilledAmount Amount of right order already filled.
/// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.
function calculateMatchedFillResults(
Order memory leftOrder,
Order memory rightOrder,
uint8 leftOrderStatus,
uint8 rightOrderStatus,
uint256 leftOrderFilledAmount,
uint256 rightOrderFilledAmount
)
internal
returns (MatchedFillResults memory matchedFillResults)
{
// We settle orders at the exchange rate of the right order.
// The amount saved by the left maker goes to the taker.
// Either the left or right order will be fully filled; possibly both.
// The left order is fully filled iff the right order can sell more than left can buy.
// That is: the amount required to fill the left order is less than or equal to
// the amount we can spend from the right order:
// <leftTakerAssetAmountRemaining> <= <rightTakerAssetAmountRemaining> * <rightMakerToTakerRatio>
// <leftTakerAssetAmountRemaining> <= <rightTakerAssetAmountRemaining> * <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount>
// <leftTakerAssetAmountRemaining> * <rightOrder.takerAssetAmount> <= <rightTakerAssetAmountRemaining> * <rightOrder.makerAssetAmount>
uint256 rightTakerAssetAmountRemaining = safeSub(rightOrder.takerAssetAmount, rightOrderFilledAmount);
uint256 leftTakerAssetAmountRemaining = safeSub(leftOrder.takerAssetAmount, leftOrderFilledAmount);
uint256 leftOrderAmountToFill;
uint256 rightOrderAmountToFill;
if (
safeMul(leftTakerAssetAmountRemaining, rightOrder.takerAssetAmount) <=
safeMul(rightTakerAssetAmountRemaining, rightOrder.makerAssetAmount)
) {
// Left order will be fully filled: maximally fill left
leftOrderAmountToFill = leftTakerAssetAmountRemaining;
// The right order receives an amount proportional to how much was spent.
// TODO: Can we ensure rounding error is in the correct direction?
rightOrderAmountToFill = safeGetPartialAmount(
rightOrder.takerAssetAmount,
rightOrder.makerAssetAmount,
leftOrderAmountToFill
);
} else {
// Right order will be fully filled: maximally fill right
rightOrderAmountToFill = rightTakerAssetAmountRemaining;
// The left order receives an amount proportional to how much was spent.
// TODO: Can we ensure rounding error is in the correct direction?
leftOrderAmountToFill = safeGetPartialAmount(
rightOrder.makerAssetAmount,
rightOrder.takerAssetAmount,
rightOrderAmountToFill
);
}
// Calculate fill results for left order
uint8 status;
(status, matchedFillResults.left) = calculateFillResults(
leftOrder,
leftOrderStatus,
leftOrderFilledAmount,
leftOrderAmountToFill
);
require(
status == uint8(Status.SUCCESS),
FAILED_TO_CALCULATE_FILL_RESULTS_FOR_LEFT_ORDER
);
// Calculate fill results for right order
(status, matchedFillResults.right) = calculateFillResults(
rightOrder,
rightOrderStatus,
rightOrderFilledAmount,
rightOrderAmountToFill
);
require(
status == uint8(Status.SUCCESS),
FAILED_TO_CALCULATE_FILL_RESULTS_FOR_RIGHT_ORDER
);
// Calculate amount given to taker
matchedFillResults.takerFillAmount = safeSub(
matchedFillResults.left.makerAssetFilledAmount,
matchedFillResults.right.takerAssetFilledAmount
);
// Validate the fill results
assertValidMatchResults(matchedFillResults);
// Return fill results
return matchedFillResults;
}
}

View File

@@ -1,171 +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.4.24;
pragma experimental ABIEncoderV2;
import "./mixins/MSettlement.sol";
import "./mixins/MAssetProxyDispatcher.sol";
import "./libs/LibOrder.sol";
import "./libs/LibMath.sol";
import "./libs/LibExchangeErrors.sol";
import "./libs/LibFillResults.sol";
import "./mixins/MMatchOrders.sol";
contract MixinSettlement is
LibMath,
LibFillResults,
LibExchangeErrors,
MMatchOrders,
MSettlement,
MAssetProxyDispatcher
{
// ZRX metadata used for fee transfers.
// This will be constant throughout the life of the Exchange contract,
// since ZRX will always be transferred via the ERC20 AssetProxy.
bytes internal ZRX_PROXY_DATA;
/// @dev Gets the ZRX metadata used for fee transfers.
function zrxProxyData()
external
view
returns (bytes memory)
{
return ZRX_PROXY_DATA;
}
/// TODO: _zrxProxyData should be a constant in production.
/// @dev Constructor sets the metadata that will be used for paying ZRX fees.
/// @param _zrxProxyData Byte array containing ERC20 proxy id concatenated with address of ZRX.
constructor (bytes memory _zrxProxyData)
public
{
ZRX_PROXY_DATA = _zrxProxyData;
}
/// @dev Settles an order by transferring assets between counterparties.
/// @param order Order struct containing order specifications.
/// @param takerAddress Address selling takerAsset and buying makerAsset.
/// @param fillResults Amounts to be filled and fees paid by maker and taker.
function settleOrder(
LibOrder.Order memory order,
address takerAddress,
FillResults memory fillResults
)
internal
{
dispatchTransferFrom(
order.makerAssetData,
order.makerAddress,
takerAddress,
fillResults.makerAssetFilledAmount
);
dispatchTransferFrom(
order.takerAssetData,
takerAddress,
order.makerAddress,
fillResults.takerAssetFilledAmount
);
dispatchTransferFrom(
ZRX_PROXY_DATA,
order.makerAddress,
order.feeRecipientAddress,
fillResults.makerFeePaid
);
dispatchTransferFrom(
ZRX_PROXY_DATA,
takerAddress,
order.feeRecipientAddress,
fillResults.takerFeePaid
);
}
/// @dev Settles matched order by transferring appropriate funds between order makers, taker, and fee recipient.
/// @param leftOrder First matched order.
/// @param rightOrder Second matched order.
/// @param takerAddress Address that matched the orders. The taker receives the spread between orders as profit.
/// @param matchedFillResults Struct holding amounts to transfer between makers, taker, and fee recipients.
function settleMatchedOrders(
LibOrder.Order memory leftOrder,
LibOrder.Order memory rightOrder,
address takerAddress,
MatchedFillResults memory matchedFillResults
)
internal
{
// Order makers and taker
dispatchTransferFrom(
leftOrder.makerAssetData,
leftOrder.makerAddress,
rightOrder.makerAddress,
matchedFillResults.right.takerAssetFilledAmount
);
dispatchTransferFrom(
rightOrder.makerAssetData,
rightOrder.makerAddress,
leftOrder.makerAddress,
matchedFillResults.left.takerAssetFilledAmount
);
dispatchTransferFrom(
leftOrder.makerAssetData,
leftOrder.makerAddress,
takerAddress,
matchedFillResults.takerFillAmount
);
// Maker fees
dispatchTransferFrom(
ZRX_PROXY_DATA,
leftOrder.makerAddress,
leftOrder.feeRecipientAddress,
matchedFillResults.left.makerFeePaid
);
dispatchTransferFrom(
ZRX_PROXY_DATA,
rightOrder.makerAddress,
rightOrder.feeRecipientAddress,
matchedFillResults.right.makerFeePaid
);
// Taker fees
if (leftOrder.feeRecipientAddress == rightOrder.feeRecipientAddress) {
dispatchTransferFrom(
ZRX_PROXY_DATA,
takerAddress,
leftOrder.feeRecipientAddress,
safeAdd(
matchedFillResults.left.takerFeePaid,
matchedFillResults.right.takerFeePaid
)
);
} else {
dispatchTransferFrom(
ZRX_PROXY_DATA,
takerAddress,
leftOrder.feeRecipientAddress,
matchedFillResults.left.takerFeePaid
);
dispatchTransferFrom(
ZRX_PROXY_DATA,
takerAddress,
rightOrder.feeRecipientAddress,
matchedFillResults.right.takerFeePaid
);
}
}
}

View File

@@ -1,238 +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.4.24;
import "./mixins/MSignatureValidator.sol";
import "./mixins/MTransactions.sol";
import "./interfaces/IWallet.sol";
import "./interfaces/IValidator.sol";
import "./libs/LibExchangeErrors.sol";
import "../../utils/LibBytes/LibBytes.sol";
contract MixinSignatureValidator is
LibBytes,
LibExchangeErrors,
MSignatureValidator,
MTransactions
{
// Mapping of hash => signer => signed
mapping (bytes32 => mapping (address => bool)) public preSigned;
// Mapping of signer => validator => approved
mapping (address => mapping (address => bool)) public allowedValidators;
/// @dev Approves a hash on-chain using any valid signature type.
/// After presigning a hash, the preSign signature type will become valid for that hash and signer.
/// @param signer Address that should have signed the given hash.
/// @param signature Proof that the hash has been signed by signer.
function preSign(
bytes32 hash,
address signer,
bytes signature
)
external
{
require(
isValidSignature(hash, signer, signature),
SIGNATURE_VALIDATION_FAILED
);
preSigned[hash][signer] = true;
}
/// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf.
/// @param validator Address of Validator contract.
/// @param approval Approval or disapproval of Validator contract.
function setSignatureValidatorApproval(
address validator,
bool approval
)
external
{
address signer = getCurrentContextAddress();
allowedValidators[signer][validator] = approval;
}
/// @dev Verifies that a hash has been signed by the given signer.
/// @param hash Any 32 byte hash.
/// @param signer Address that should have signed the given hash.
/// @param signature Proof that the hash has been signed by signer.
/// @return True if the address recovered from the provided signature matches the input signer address.
function isValidSignature(
bytes32 hash,
address signer,
bytes memory signature
)
internal
view
returns (bool isValid)
{
// TODO: Domain separation: make hash depend on role. (Taker sig should not be valid as maker sig, etc.)
require(
signature.length >= 1,
INVALID_SIGNATURE_LENGTH
);
// Pop last byte off of signature byte array.
SignatureType signatureType = SignatureType(uint8(popByte(signature)));
// Variables are not scoped in Solidity.
uint8 v;
bytes32 r;
bytes32 s;
address recovered;
// Always illegal signature.
// This is always an implicit option since a signer can create a
// signature array with invalid type or length. We may as well make
// it an explicit option. This aids testing and analysis. It is
// also the initialization value for the enum type.
if (signatureType == SignatureType.Illegal) {
revert(ILLEGAL_SIGNATURE_TYPE);
// 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,
INVALID_SIGNATURE_LENGTH
);
isValid = false;
return isValid;
// Signature using EIP712
} else if (signatureType == SignatureType.EIP712) {
require(
signature.length == 65,
INVALID_SIGNATURE_LENGTH
);
v = uint8(signature[0]);
r = readBytes32(signature, 1);
s = readBytes32(signature, 33);
recovered = ecrecover(hash, v, r, s);
isValid = signer == recovered;
return isValid;
// Signed using web3.eth_sign
} else if (signatureType == SignatureType.EthSign) {
require(
signature.length == 65,
INVALID_SIGNATURE_LENGTH
);
v = uint8(signature[0]);
r = readBytes32(signature, 1);
s = readBytes32(signature, 33);
recovered = ecrecover(
keccak256("\x19Ethereum Signed Message:\n32", hash),
v,
r,
s
);
isValid = signer == recovered;
return isValid;
// Implicitly signed by caller.
// The signer has initiated the call. In the case of non-contract
// accounts it means the transaction itself was signed.
// Example: let's say for a particular operation three signatures
// A, B and C are required. To submit the transaction, A and B can
// give a signature to C, who can then submit the transaction using
// `Caller` for his own signature. Or A and C can sign and B can
// submit using `Caller`. Having `Caller` allows this flexibility.
} else if (signatureType == SignatureType.Caller) {
require(
signature.length == 0,
INVALID_SIGNATURE_LENGTH
);
isValid = signer == msg.sender;
return isValid;
// Signature verified by wallet contract.
// If used with an order, the maker of the order is the wallet contract.
} else if (signatureType == SignatureType.Wallet) {
isValid = IWallet(signer).isValidSignature(hash, signature);
return isValid;
// Signature verified by validator contract.
// If used with an order, the maker of the order can still be an EOA.
// A signature using this type should be encoded as:
// | Offset | Length | Contents |
// | 0x00 | x | Signature to validate |
// | 0x00 + x | 20 | Address of validator contract |
// | 0x14 + x | 1 | Signature type is always "\x06" |
} else if (signatureType == SignatureType.Validator) {
// Pop last 20 bytes off of signature byte array.
address validator = popAddress(signature);
// Ensure signer has approved validator.
if (!allowedValidators[signer][validator]) {
return false;
}
isValid = IValidator(validator).isValidSignature(
hash,
signer,
signature
);
return isValid;
// Signer signed hash previously using the preSign function.
} else if (signatureType == SignatureType.PreSigned) {
isValid = preSigned[hash][signer];
return isValid;
// Signature from Trezor hardware wallet.
// It differs from web3.eth_sign in the encoding of message length
// (Bitcoin varint encoding vs ascii-decimal, the latter is not
// self-terminating which leads to ambiguities).
// See also:
// https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
// https://github.com/trezor/trezor-mcu/blob/master/firmware/ethereum.c#L602
// https://github.com/trezor/trezor-mcu/blob/master/firmware/crypto.c#L36
} else if (signatureType == SignatureType.Trezor) {
require(
signature.length == 65,
INVALID_SIGNATURE_LENGTH
);
v = uint8(signature[0]);
r = readBytes32(signature, 1);
s = readBytes32(signature, 33);
recovered = ecrecover(
keccak256("\x19Ethereum Signed Message:\n\x41", hash),
v,
r,
s
);
isValid = signer == recovered;
return isValid;
// Signer signed hash previously using the preSign function
} else if (signatureType == SignatureType.PreSigned) {
isValid = preSigned[hash][signer];
return isValid;
}
// Anything else is illegal (We do not return false because
// the signature may actually be valid, just not in a format
// that we currently support. In this case returning false
// may lead the caller to incorrectly believe that the
// signature was invalid.)
revert(UNSUPPORTED_SIGNATURE_TYPE);
}
}

View File

@@ -1,107 +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.4.24;
import "./mixins/MSignatureValidator.sol";
import "./mixins/MTransactions.sol";
import "./libs/LibExchangeErrors.sol";
contract MixinTransactions is
LibExchangeErrors,
MSignatureValidator,
MTransactions
{
// Mapping of transaction hash => executed
// This prevents transactions from being executed more than once.
mapping (bytes32 => bool) public transactions;
// Address of current transaction signer
address public currentContextAddress;
/// @dev Executes an exchange method call in the context of signer.
/// @param salt Arbitrary number to ensure uniqueness of transaction hash.
/// @param signer Address of transaction signer.
/// @param data AbiV2 encoded calldata.
/// @param signature Proof of signer transaction by signer.
function executeTransaction(
uint256 salt,
address signer,
bytes data,
bytes signature
)
external
{
// Prevent reentrancy
require(
currentContextAddress == address(0),
REENTRANCY_NOT_ALLOWED
);
// Calculate transaction hash
bytes32 transactionHash = keccak256(
address(this),
signer,
salt,
data
);
// Validate transaction has not been executed
require(
!transactions[transactionHash],
DUPLICATE_TRANSACTION_HASH
);
// TODO: is SignatureType.Caller necessary if we make this check?
if (signer != msg.sender) {
// Validate signature
require(
isValidSignature(transactionHash, signer, signature),
SIGNATURE_VALIDATION_FAILED
);
// Set the current transaction signer
currentContextAddress = signer;
}
// Execute transaction
transactions[transactionHash] = true;
require(
address(this).delegatecall(data),
TRANSACTION_EXECUTION_FAILED
);
// Reset current transaction signer
// TODO: Check if gas is paid when currentContextAddress is already 0.
currentContextAddress = address(0);
}
/// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`).
/// If calling a fill function, this address will represent the taker.
/// If calling a cancel function, this address will represent the maker.
/// @return Signer of 0x transaction if entry point is `executeTransaction`.
/// `msg.sender` if entry point is any other function.
function getCurrentContextAddress()
internal
view
returns (address)
{
address contextAddress = currentContextAddress == address(0) ? msg.sender : currentContextAddress;
return contextAddress;
}
}

View File

@@ -1,515 +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.4.24;
pragma experimental ABIEncoderV2;
import "../../utils/LibBytes/LibBytes.sol";
import "./mixins/MExchangeCore.sol";
import "./libs/LibMath.sol";
import "./libs/LibOrder.sol";
import "./libs/LibFillResults.sol";
import "./libs/LibExchangeErrors.sol";
contract MixinWrapperFunctions is
SafeMath,
LibBytes,
LibMath,
LibOrder,
LibFillResults,
LibExchangeErrors,
MExchangeCore
{
/// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
/// @param order Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
function fillOrKillOrder(
Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (FillResults memory fillResults)
{
fillResults = fillOrder(
order,
takerAssetFillAmount,
signature
);
require(
fillResults.takerAssetFilledAmount == takerAssetFillAmount,
COMPLETE_FILL_FAILED
);
return fillResults;
}
/// @dev Fills an order with specified parameters and ECDSA signature.
/// Returns false if the transaction would otherwise revert.
/// @param order Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
/// @return Amounts filled and fees paid by maker and taker.
function fillOrderNoThrow(
Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (FillResults memory fillResults)
{
// We need to call MExchangeCore.fillOrder using a delegatecall in
// assembly so that we can intercept a call that throws. For this, we
// need the input encoded in memory in the Ethereum ABIv2 format [1].
// | Area | Offset | Length | Contents |
// | -------- |--------|---------|-------------------------------------------- |
// | Header | 0x00 | 4 | function selector |
// | Params | | 3 * 32 | function parameters: |
// | | 0x00 | | 1. offset to order (*) |
// | | 0x20 | | 2. takerAssetFillAmount |
// | | 0x40 | | 3. offset to signature (*) |
// | Data | | 12 * 32 | order: |
// | | 0x000 | | 1. senderAddress |
// | | 0x020 | | 2. makerAddress |
// | | 0x040 | | 3. takerAddress |
// | | 0x060 | | 4. feeRecipientAddress |
// | | 0x080 | | 5. makerAssetAmount |
// | | 0x0A0 | | 6. takerAssetAmount |
// | | 0x0C0 | | 7. makerFeeAmount |
// | | 0x0E0 | | 8. takerFeeAmount |
// | | 0x100 | | 9. expirationTimeSeconds |
// | | 0x120 | | 10. salt |
// | | 0x140 | | 11. Offset to makerAssetProxyMetadata (*) |
// | | 0x160 | | 12. Offset to takerAssetProxyMetadata (*) |
// | | 0x180 | 32 | makerAssetProxyMetadata Length |
// | | 0x1A0 | ** | makerAssetProxyMetadata Contents |
// | | 0x1C0 | 32 | takerAssetProxyMetadata Length |
// | | 0x1E0 | ** | takerAssetProxyMetadata Contents |
// | | 0x200 | 32 | signature Length |
// | | 0x220 | ** | signature Contents |
// * Offsets are calculated from the beginning of the current area: Header, Params, Data:
// An offset stored in the Params area is calculated from the beginning of the Params section.
// An offset stored in the Data area is calculated from the beginning of the Data section.
// ** The length of dynamic array contents are stored in the field immediately preceeding the contents.
// [1]: https://solidity.readthedocs.io/en/develop/abi-spec.html
bytes4 fillOrderSelector = this.fillOrder.selector;
assembly {
// Areas below may use the following variables:
// 1. <area>Start -- Start of this area in memory
// 2. <area>End -- End of this area in memory. This value may
// be precomputed (before writing contents),
// or it may be computed as contents are written.
// 3. <area>Offset -- Current offset into area. If an area's End
// is precomputed, this variable tracks the
// offsets of contents as they are written.
/////// Setup Header Area ///////
// Load free memory pointer
let headerAreaStart := mload(0x40)
mstore(headerAreaStart, fillOrderSelector)
let headerAreaEnd := add(headerAreaStart, 0x4)
/////// Setup Params Area ///////
// This area is preallocated and written to later.
// This is because we need to fill in offsets that have not yet been calculated.
let paramsAreaStart := headerAreaEnd
let paramsAreaEnd := add(paramsAreaStart, 0x60)
let paramsAreaOffset := paramsAreaStart
/////// Setup Data Area ///////
let dataAreaStart := paramsAreaEnd
let dataAreaEnd := dataAreaStart
// Offset from the source data we're reading from
let sourceOffset := order
// arrayLenBytes and arrayLenWords track the length of a dynamically-allocated bytes array.
let arrayLenBytes := 0
let arrayLenWords := 0
/////// Write order Struct ///////
// Write memory location of Order, relative to the start of the
// parameter list, then increment the paramsAreaOffset respectively.
mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))
paramsAreaOffset := add(paramsAreaOffset, 0x20)
// Write values for each field in the order
// It would be nice to use a loop, but we save on gas by writing
// the stores sequentially.
mstore(dataAreaEnd, mload(sourceOffset)) // makerAddress
mstore(add(dataAreaEnd, 0x20), mload(add(sourceOffset, 0x20))) // takerAddress
mstore(add(dataAreaEnd, 0x40), mload(add(sourceOffset, 0x40))) // feeRecipientAddress
mstore(add(dataAreaEnd, 0x60), mload(add(sourceOffset, 0x60))) // senderAddress
mstore(add(dataAreaEnd, 0x80), mload(add(sourceOffset, 0x80))) // makerAssetAmount
mstore(add(dataAreaEnd, 0xA0), mload(add(sourceOffset, 0xA0))) // takerAssetAmount
mstore(add(dataAreaEnd, 0xC0), mload(add(sourceOffset, 0xC0))) // makerFeeAmount
mstore(add(dataAreaEnd, 0xE0), mload(add(sourceOffset, 0xE0))) // takerFeeAmount
mstore(add(dataAreaEnd, 0x100), mload(add(sourceOffset, 0x100))) // expirationTimeSeconds
mstore(add(dataAreaEnd, 0x120), mload(add(sourceOffset, 0x120))) // salt
mstore(add(dataAreaEnd, 0x140), mload(add(sourceOffset, 0x140))) // Offset to makerAssetProxyMetadata
mstore(add(dataAreaEnd, 0x160), mload(add(sourceOffset, 0x160))) // Offset to takerAssetProxyMetadata
dataAreaEnd := add(dataAreaEnd, 0x180)
sourceOffset := add(sourceOffset, 0x180)
// Write offset to <order.makerAssetProxyMetadata>
mstore(add(dataAreaStart, mul(10, 0x20)), sub(dataAreaEnd, dataAreaStart))
// Calculate length of <order.makerAssetProxyMetadata>
arrayLenBytes := mload(sourceOffset)
sourceOffset := add(sourceOffset, 0x20)
arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)
// Write length of <order.makerAssetProxyMetadata>
mstore(dataAreaEnd, arrayLenBytes)
dataAreaEnd := add(dataAreaEnd, 0x20)
// Write contents of <order.makerAssetProxyMetadata>
for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {
mstore(dataAreaEnd, mload(sourceOffset))
dataAreaEnd := add(dataAreaEnd, 0x20)
sourceOffset := add(sourceOffset, 0x20)
}
// Write offset to <order.takerAssetProxyMetadata>
mstore(add(dataAreaStart, mul(11, 0x20)), sub(dataAreaEnd, dataAreaStart))
// Calculate length of <order.takerAssetProxyMetadata>
arrayLenBytes := mload(sourceOffset)
sourceOffset := add(sourceOffset, 0x20)
arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)
// Write length of <order.takerAssetProxyMetadata>
mstore(dataAreaEnd, arrayLenBytes)
dataAreaEnd := add(dataAreaEnd, 0x20)
// Write contents of <order.takerAssetProxyMetadata>
for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {
mstore(dataAreaEnd, mload(sourceOffset))
dataAreaEnd := add(dataAreaEnd, 0x20)
sourceOffset := add(sourceOffset, 0x20)
}
/////// Write takerAssetFillAmount ///////
mstore(paramsAreaOffset, takerAssetFillAmount)
paramsAreaOffset := add(paramsAreaOffset, 0x20)
/////// Write signature ///////
// Write offset to paramsArea
mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))
// Calculate length of signature
sourceOffset := signature
arrayLenBytes := mload(sourceOffset)
sourceOffset := add(sourceOffset, 0x20)
arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)
// Write length of signature
mstore(dataAreaEnd, arrayLenBytes)
dataAreaEnd := add(dataAreaEnd, 0x20)
// Write contents of signature
for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {
mstore(dataAreaEnd, mload(sourceOffset))
dataAreaEnd := add(dataAreaEnd, 0x20)
sourceOffset := add(sourceOffset, 0x20)
}
// Execute delegatecall
let success := delegatecall(
gas, // forward all gas, TODO: look into gas consumption of assert/throw
address, // call address of this contract
headerAreaStart, // pointer to start of input
sub(dataAreaEnd, headerAreaStart), // length of input
headerAreaStart, // write output over input
128 // output size is 128 bytes
)
switch success
case 0 {
mstore(fillResults, 0)
mstore(add(fillResults, 32), 0)
mstore(add(fillResults, 64), 0)
mstore(add(fillResults, 96), 0)
}
case 1 {
mstore(fillResults, mload(headerAreaStart))
mstore(add(fillResults, 32), mload(add(headerAreaStart, 32)))
mstore(add(fillResults, 64), mload(add(headerAreaStart, 64)))
mstore(add(fillResults, 96), mload(add(headerAreaStart, 96)))
}
}
return fillResults;
}
/// @dev Synchronously executes multiple calls of fillOrder.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrders(
Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public
{
for (uint256 i = 0; i < orders.length; i++) {
fillOrder(
orders[i],
takerAssetFillAmounts[i],
signatures[i]
);
}
}
/// @dev Synchronously executes multiple calls of fillOrKill.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrKillOrders(
Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public
{
for (uint256 i = 0; i < orders.length; i++) {
fillOrKillOrder(
orders[i],
takerAssetFillAmounts[i],
signatures[i]
);
}
}
/// @dev Fills an order with specified parameters and ECDSA signature.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrdersNoThrow(
Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public
{
for (uint256 i = 0; i < orders.length; i++) {
fillOrderNoThrow(
orders[i],
takerAssetFillAmounts[i],
signatures[i]
);
}
}
/// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signatures Proofs that orders have been created by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketSellOrders(
Order[] memory orders,
uint256 takerAssetFillAmount,
bytes[] memory signatures)
public
returns (FillResults memory totalFillResults)
{
for (uint256 i = 0; i < orders.length; i++) {
// Token being sold by taker must be the same for each order
// TODO: optimize by only using takerAssetData for first order.
require(
areBytesEqual(orders[i].takerAssetData, orders[0].takerAssetData),
ASSET_DATA_MISMATCH
);
// Calculate the remaining amount of takerAsset to sell
uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);
// Attempt to sell the remaining amount of takerAsset
FillResults memory singleFillResults = fillOrder(
orders[i],
remainingTakerAssetFillAmount,
signatures[i]
);
// Update amounts filled and fees paid by maker and taker
addFillResults(totalFillResults, singleFillResults);
// Stop execution if the entire amount of takerAsset has been sold
if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {
break;
}
}
return totalFillResults;
}
/// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketSellOrdersNoThrow(
Order[] memory orders,
uint256 takerAssetFillAmount,
bytes[] memory signatures)
public
returns (FillResults memory totalFillResults)
{
for (uint256 i = 0; i < orders.length; i++) {
// Token being sold by taker must be the same for each order
// TODO: optimize by only using takerAssetData for first order.
require(
areBytesEqual(orders[i].takerAssetData, orders[0].takerAssetData),
ASSET_DATA_MISMATCH
);
// Calculate the remaining amount of takerAsset to sell
uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);
// Attempt to sell the remaining amount of takerAsset
FillResults memory singleFillResults = fillOrderNoThrow(
orders[i],
remainingTakerAssetFillAmount,
signatures[i]
);
// Update amounts filled and fees paid by maker and taker
addFillResults(totalFillResults, singleFillResults);
// Stop execution if the entire amount of takerAsset has been sold
if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) {
break;
}
}
return totalFillResults;
}
/// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.
/// @param orders Array of order specifications.
/// @param makerAssetFillAmount Desired amount of makerAsset to buy.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketBuyOrders(
Order[] memory orders,
uint256 makerAssetFillAmount,
bytes[] memory signatures)
public
returns (FillResults memory totalFillResults)
{
for (uint256 i = 0; i < orders.length; i++) {
// Token being bought by taker must be the same for each order
// TODO: optimize by only using makerAssetData for first order.
require(
areBytesEqual(orders[i].makerAssetData, orders[0].makerAssetData),
ASSET_DATA_MISMATCH
);
// Calculate the remaining amount of makerAsset to buy
uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);
// Convert the remaining amount of makerAsset to buy into remaining amount
// of takerAsset to sell, assuming entire amount can be sold in the current order
uint256 remainingTakerAssetFillAmount = getPartialAmount(
orders[i].takerAssetAmount,
orders[i].makerAssetAmount,
remainingMakerAssetFillAmount
);
// Attempt to sell the remaining amount of takerAsset
FillResults memory singleFillResults = fillOrder(
orders[i],
remainingTakerAssetFillAmount,
signatures[i]
);
// Update amounts filled and fees paid by maker and taker
addFillResults(totalFillResults, singleFillResults);
// Stop execution if the entire amount of makerAsset has been bought
if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {
break;
}
}
return totalFillResults;
}
/// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param makerAssetFillAmount Desired amount of makerAsset to buy.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketBuyOrdersNoThrow(
Order[] memory orders,
uint256 makerAssetFillAmount,
bytes[] memory signatures)
public
returns (FillResults memory totalFillResults)
{
for (uint256 i = 0; i < orders.length; i++) {
// Token being bought by taker must be the same for each order
// TODO: optimize by only using makerAssetData for first order.
require(
areBytesEqual(orders[i].makerAssetData, orders[0].makerAssetData),
ASSET_DATA_MISMATCH
);
// Calculate the remaining amount of makerAsset to buy
uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);
// Convert the remaining amount of makerAsset to buy into remaining amount
// of takerAsset to sell, assuming entire amount can be sold in the current order
uint256 remainingTakerAssetFillAmount = getPartialAmount(
orders[i].takerAssetAmount,
orders[i].makerAssetAmount,
remainingMakerAssetFillAmount
);
// Attempt to sell the remaining amount of takerAsset
FillResults memory singleFillResults = fillOrderNoThrow(
orders[i],
remainingTakerAssetFillAmount,
signatures[i]
);
// Update amounts filled and fees paid by maker and taker
addFillResults(totalFillResults, singleFillResults);
// Stop execution if the entire amount of makerAsset has been bought
if (totalFillResults.makerAssetFilledAmount == makerAssetFillAmount) {
break;
}
}
return totalFillResults;
}
/// @dev Synchronously cancels multiple orders in a single transaction.
/// @param orders Array of order specifications.
function batchCancelOrders(Order[] memory orders)
public
{
for (uint256 i = 0; i < orders.length; i++) {
cancelOrder(orders[i]);
}
}
}

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.4.24;
contract IAssetProxyDispatcher {
/// @dev Registers an asset proxy to an asset proxy id.
/// An id can only be assigned to a single proxy at a given time.
/// @param assetProxyId Id to register`newAssetProxy` under.
/// @param newAssetProxy Address of new asset proxy to register, or 0x0 to unset assetProxyId.
/// @param oldAssetProxy Existing asset proxy to overwrite, or 0x0 if assetProxyId is currently unused.
function registerAssetProxy(
uint8 assetProxyId,
address newAssetProxy,
address oldAssetProxy)
external;
/// @dev Gets an asset proxy.
/// @param assetProxyId Id of the asset proxy.
/// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.
function getAssetProxy(uint8 assetProxyId)
external
view
returns (address);
}

View File

@@ -1,36 +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.4.24;
pragma experimental ABIEncoderV2;
import "./IExchangeCore.sol";
import "./IMatchOrders.sol";
import "./ISignatureValidator.sol";
import "./ITransactions.sol";
import "./IAssetProxyDispatcher.sol";
import "./IWrapperFunctions.sol";
contract IExchange is
IExchangeCore,
IMatchOrders,
ISignatureValidator,
ITransactions,
IAssetProxyDispatcher,
IWrapperFunctions
{}

View File

@@ -1,80 +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.4.24;
pragma experimental ABIEncoderV2;
import "../libs/LibOrder.sol";
import "../libs/LibFillResults.sol";
contract IExchangeCore {
/// @dev Cancels all orders reated by sender with a salt less than or equal to the specified salt value.
/// @param salt Orders created with a salt less or equal to this value will be cancelled.
function cancelOrdersUpTo(uint256 salt)
external;
/// @dev Fills the input order.
/// @param order Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
/// @return Amounts filled and fees paid by maker and taker.
function fillOrder(
LibOrder.Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (LibFillResults.FillResults memory fillResults);
/// @dev After calling, the order can not be filled anymore.
/// @param order Order struct containing order specifications.
/// @return True if the order state changed to cancelled.
/// False if the transaction was already cancelled or expired.
function cancelOrder(LibOrder.Order memory order)
public
returns (bool);
/// @dev Gets information about an order: status, hash, and amount filled.
/// @param order Order to gather information on.
/// @return OrderInfo Information about the order and its state.
/// See LibOrder.OrderInfo for a complete description.
function getOrderInfo(LibOrder.Order memory order)
public
view
returns (LibOrder.OrderInfo memory orderInfo);
/// @dev Calculates amounts filled and fees paid by maker and taker.
/// @param order to be filled.
/// @param orderStatus Status of order to be filled.
/// @param orderTakerAssetFilledAmount Amount of order already filled.
/// @param takerAssetFillAmount Desired amount of order to fill by taker.
/// @return status Return status of calculating fill amounts. Returns Status.SUCCESS on success.
/// @return fillResults Amounts filled and fees paid by maker and taker.
function calculateFillResults(
LibOrder.Order memory order,
uint8 orderStatus,
uint256 orderTakerAssetFilledAmount,
uint256 takerAssetFillAmount
)
public
pure
returns (
uint8 status,
LibFillResults.FillResults memory fillResults
);
}

View File

@@ -1,44 +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.4.24;
pragma experimental ABIEncoderV2;
import "../libs/LibOrder.sol";
import "../libs/LibFillResults.sol";
contract IMatchOrders {
/// @dev Match two complementary orders that have a profitable spread.
/// Each order is filled at their respective price point. However, the calculations are
/// carried out as though the orders are both being filled at the right order's price point.
/// The profit made by the left order goes to the taker (who matched the two orders).
/// @param leftOrder First order to match.
/// @param rightOrder Second order to match.
/// @param leftSignature Proof that order was created by the left maker.
/// @param rightSignature Proof that order was created by the right maker.
/// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders.
/// TODO: Make this function external once supported by Solidity (See Solidity Issues #3199, #1603)
function matchOrders(
LibOrder.Order memory leftOrder,
LibOrder.Order memory rightOrder,
bytes memory leftSignature,
bytes memory rightSignature
)
public
returns (LibFillResults.MatchedFillResults memory matchedFillResults);
}

View File

@@ -1,42 +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.4.24;
contract ISignatureValidator {
/// @dev Approves a hash on-chain using any valid signature type.
/// After presigning a hash, the preSign signature type will become valid for that hash and signer.
/// @param signer Address that should have signed the given hash.
/// @param signature Proof that the hash has been signed by signer.
function preSign(
bytes32 hash,
address signer,
bytes signature
)
external;
/// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf.
/// @param validator Address of Validator contract.
/// @param approval Approval or disapproval of Validator contract.
function setSignatureValidatorApproval(
address validator,
bool approval
)
external;
}

View File

@@ -1,33 +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.4.24;
contract ITransactions {
/// @dev Executes an exchange method call in the context of signer.
/// @param salt Arbitrary number to ensure uniqueness of transaction hash.
/// @param signer Address of transaction signer.
/// @param data AbiV2 encoded calldata.
/// @param signature Proof of signer transaction by signer.
function executeTransaction(
uint256 salt,
address signer,
bytes data,
bytes signature)
external;
}

View File

@@ -1,36 +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.4.23;
contract IValidator {
/// @dev Verifies that a signature is valid.
/// @param hash Message hash that is signed.
/// @param signer Address that should have signed the given hash.
/// @param signature Proof of signing.
/// @return Validity of order signature.
function isValidSignature(
bytes32 hash,
address signer,
bytes signature
)
external
view
returns (bool isValid);
}

View File

@@ -1,34 +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.4.24;
contract IWallet {
/// @dev Verifies that a signature is valid.
/// @param hash Message hash that is signed.
/// @param signature Proof of signing.
/// @return Validity of order signature.
function isValidSignature(
bytes32 hash,
bytes signature
)
external
view
returns (bool isValid);
}

View File

@@ -1,138 +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.4.24;
pragma experimental ABIEncoderV2;
import "../libs/LibOrder.sol";
import "../libs/LibFillResults.sol";
contract IWrapperFunctions is
LibOrder,
LibFillResults
{
/// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
/// @param order LibOrder.Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
function fillOrKillOrder(
LibOrder.Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (LibFillResults.FillResults memory fillResults);
/// @dev Fills an order with specified parameters and ECDSA signature.
/// Returns false if the transaction would otherwise revert.
/// @param order LibOrder.Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
/// @return Amounts filled and fees paid by maker and taker.
function fillOrderNoThrow(
LibOrder.Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (LibFillResults.FillResults memory fillResults);
/// @dev Synchronously executes multiple calls of fillOrder.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrders(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public;
/// @dev Synchronously executes multiple calls of fillOrKill.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrKillOrders(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public;
/// @dev Fills an order with specified parameters and ECDSA signature.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrdersNoThrow(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public;
/// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signatures Proofs that orders have been created by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketSellOrders(
LibOrder.Order[] memory orders,
uint256 takerAssetFillAmount,
bytes[] memory signatures)
public
returns (LibFillResults.FillResults memory totalFillResults);
/// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketSellOrdersNoThrow(
LibOrder.Order[] memory orders,
uint256 takerAssetFillAmount,
bytes[] memory signatures)
public
returns (LibFillResults.FillResults memory totalFillResults);
/// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.
/// @param orders Array of order specifications.
/// @param makerAssetFillAmount Desired amount of makerAsset to buy.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketBuyOrders(
LibOrder.Order[] memory orders,
uint256 makerAssetFillAmount,
bytes[] memory signatures)
public
returns (LibFillResults.FillResults memory totalFillResults);
/// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param makerAssetFillAmount Desired amount of makerAsset to buy.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketBuyOrdersNoThrow(
LibOrder.Order[] memory orders,
uint256 makerAssetFillAmount,
bytes[] memory signatures)
public
returns (LibFillResults.FillResults memory totalFillResults);
/// @dev Synchronously cancels multiple orders in a single transaction.
/// @param orders Array of order specifications.
function batchCancelOrders(LibOrder.Order[] memory orders)
public;
}

View File

@@ -1,61 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.24;
contract LibExchangeErrors {
// Core revert reasons
string constant GT_ZERO_AMOUNT_REQUIRED = "Amount must be greater than 0.";
string constant SIGNATURE_VALIDATION_FAILED = "Signature validation failed.";
string constant INVALID_SENDER = "Invalid `msg.sender`.";
string constant INVALID_CONTEXT = "Function called in an invalid context.";
string constant INVALID_NEW_MAKER_EPOCH = "Specified salt must be greater than or equal to existing makerEpoch.";
// Order revert reasons
string constant INVALID_ORDER_TAKER_ASSET_AMOUNT = "Invalid order taker asset amount: expected a non-zero value.";
string constant INVALID_ORDER_MAKER_ASSET_AMOUNT = "Invalid order maker asset amount: expected a non-zero value.";
// Transaction revert reasons
string constant REENTRANCY_NOT_ALLOWED = "`executeTransaction` is not allowed to call itself recursively.";
string constant DUPLICATE_TRANSACTION_HASH = "Transaction has already been executed.";
string constant TRANSACTION_EXECUTION_FAILED = "Transaction execution failed.";
// Wrapper revert reasons
string constant COMPLETE_FILL_FAILED = "Desired fill amount could not be completely filled.";
string constant ASSET_DATA_MISMATCH = "Asset data must be the same for each order.";
// Asset proxy dispatcher revert reasons
string constant GT_ZERO_LENGTH_REQUIRED = "Length must be greater than 0.";
string constant OLD_ASSET_PROXY_MISMATCH = "Old asset proxy does not match asset proxy at given id.";
string constant NEW_ASSET_PROXY_MISMATCH = "New asset proxy id does not match given id.";
// Signature validator revert reasons
string constant INVALID_SIGNATURE_LENGTH = "Invalid signature length.";
string constant ILLEGAL_SIGNATURE_TYPE = "Illegal signature type.";
string constant UNSUPPORTED_SIGNATURE_TYPE = "Unsupported signature type.";
// Order matching revert reasons
string constant ASSET_MISMATCH_MAKER_TAKER = "Left order maker asset is different from right order taker asset.";
string constant ASSET_MISMATCH_TAKER_MAKER = "Left order taker asset is different from right order maker asset.";
string constant NEGATIVE_SPREAD = "Matched orders must have a positive spread.";
string constant MISCALCULATED_TRANSFER_AMOUNTS = "A miscalculation occurred: the left maker would receive more than the right maker would spend.";
string constant ROUNDING_ERROR_TRANSFER_AMOUNTS = "A rounding error occurred when calculating transfer amounts for matched orders.";
string constant FAILED_TO_CALCULATE_FILL_RESULTS_FOR_LEFT_ORDER = "Failed to calculate fill results for left order.";
string constant FAILED_TO_CALCULATE_FILL_RESULTS_FOR_RIGHT_ORDER = "Failed to calculate fill results for right order.";
}

View File

@@ -1,68 +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.4.24;
import "../../../utils/SafeMath/SafeMath.sol";
contract LibFillResults is
SafeMath
{
struct FillResults {
uint256 makerAssetFilledAmount;
uint256 takerAssetFilledAmount;
uint256 makerFeePaid;
uint256 takerFeePaid;
}
struct MatchedFillResults {
LibFillResults.FillResults left;
LibFillResults.FillResults right;
uint256 takerFillAmount;
}
/// @dev Adds properties of both FillResults instances.
/// Modifies the first FillResults instance specified.
/// @param totalFillResults Fill results instance that will be added onto.
/// @param singleFillResults Fill results instance that will be added to totalFillResults.
function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)
internal
pure
{
totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);
totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);
totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);
totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);
}
/// @dev Returns a null fill results struct
function getNullFillResults()
internal
pure
returns (FillResults memory)
{
// returns zeroed out FillResults instance
return FillResults({
makerAssetFilledAmount: 0,
takerAssetFilledAmount: 0,
makerFeePaid: 0,
takerFeePaid: 0
});
}
}

View File

@@ -1,93 +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.4.24;
import "../../../utils/SafeMath/SafeMath.sol";
contract LibMath is
SafeMath
{
string constant ROUNDING_ERROR_ON_PARTIAL_AMOUNT = "A rounding error occurred when calculating partial transfer amounts.";
/// @dev Calculates partial value given a numerator and denominator.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to calculate partial of.
/// @return Partial value of target.
function getPartialAmount(
uint256 numerator,
uint256 denominator,
uint256 target)
internal
pure
returns (uint256 partialAmount)
{
partialAmount = safeDiv(
safeMul(numerator, target),
denominator
);
return partialAmount;
}
/// @dev Calculates partial value given a numerator and denominator.
/// Throws if there is a rounding error.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to calculate partial of.
/// @return Partial value of target.
function safeGetPartialAmount(
uint256 numerator,
uint256 denominator,
uint256 target)
internal pure
returns (uint256 partialAmount)
{
require(
!isRoundingError(numerator, denominator, target),
ROUNDING_ERROR_ON_PARTIAL_AMOUNT
);
return getPartialAmount(numerator, denominator, target);
}
/// @dev Checks if rounding error > 0.1%.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator.
/// @return Rounding error is present.
function isRoundingError(
uint256 numerator,
uint256 denominator,
uint256 target)
internal
pure
returns (bool isError)
{
uint256 remainder = mulmod(target, numerator, denominator);
if (remainder == 0) {
return false; // No rounding error.
}
uint256 errPercentageTimes1000000 = safeDiv(
safeMul(remainder, 1000000),
safeMul(numerator, target)
);
isError = errPercentageTimes1000000 > 1000;
return isError;
}
}

View File

@@ -1,99 +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.4.24;
contract LibOrder {
bytes32 constant DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(
"DomainSeparator(address contract)"
);
bytes32 constant ORDER_SCHEMA_HASH = keccak256(
"Order(",
"address makerAddress,",
"address takerAddress,",
"address feeRecipientAddress,",
"address senderAddress,",
"uint256 makerAssetAmount,",
"uint256 takerAssetAmount,",
"uint256 makerFee,",
"uint256 takerFee,",
"uint256 expirationTimeSeconds,",
"uint256 salt,",
"bytes makerAssetData,",
"bytes takerAssetData,",
")"
);
struct Order {
address makerAddress;
address takerAddress;
address feeRecipientAddress;
address senderAddress;
uint256 makerAssetAmount;
uint256 takerAssetAmount;
uint256 makerFee;
uint256 takerFee;
uint256 expirationTimeSeconds;
uint256 salt;
bytes makerAssetData;
bytes takerAssetData;
}
struct OrderInfo {
// See LibStatus for a complete description of order statuses
uint8 orderStatus;
// Keccak-256 EIP712 hash of the order
bytes32 orderHash;
// Amount of order that has been filled
uint256 orderTakerAssetFilledAmount;
}
/// @dev Calculates Keccak-256 hash of the order.
/// @param order The order structure.
/// @return Keccak-256 EIP712 hash of the order.
function getOrderHash(Order memory order)
internal
view
returns (bytes32 orderHash)
{
// TODO: EIP712 is not finalized yet
// Source: https://github.com/ethereum/EIPs/pull/712
orderHash = keccak256(
DOMAIN_SEPARATOR_SCHEMA_HASH,
keccak256(address(this)),
ORDER_SCHEMA_HASH,
keccak256(
order.makerAddress,
order.takerAddress,
order.feeRecipientAddress,
order.senderAddress,
order.makerAssetAmount,
order.takerAssetAmount,
order.makerFee,
order.takerFee,
order.expirationTimeSeconds,
order.salt,
keccak256(order.makerAssetData),
keccak256(order.takerAssetData)
)
);
return orderHash;
}
}

View File

@@ -1,51 +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.4.24;
pragma experimental ABIEncoderV2;
contract LibStatus {
// Exchange Status Codes
enum Status {
/// Default Status ///
INVALID, // General invalid status
/// General Exchange Statuses ///
SUCCESS, // Indicates a successful operation
ROUNDING_ERROR_TOO_LARGE, // Rounding error too large
INSUFFICIENT_BALANCE_OR_ALLOWANCE, // Insufficient balance or allowance for token transfer
TAKER_ASSET_FILL_AMOUNT_TOO_LOW, // takerAssetFillAmount is <= 0
INVALID_SIGNATURE, // Invalid signature
INVALID_SENDER, // Invalid sender
INVALID_TAKER, // Invalid taker
INVALID_MAKER, // Invalid maker
/// Order State Statuses ///
// A valid order remains fillable until it is expired, fully filled, or cancelled.
// An order's state is unaffected by external factors, like account balances.
ORDER_INVALID_MAKER_ASSET_AMOUNT, // Order does not have a valid maker asset amount
ORDER_INVALID_TAKER_ASSET_AMOUNT, // Order does not have a valid taker asset amount
ORDER_FILLABLE, // Order is fillable
ORDER_EXPIRED, // Order has already expired
ORDER_FULLY_FILLED, // Order is fully filled
ORDER_CANCELLED // Order has been cancelled
}
event ExchangeStatus(uint8 indexed statusId, bytes32 indexed orderHash);
}

View File

@@ -1,47 +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.4.24;
pragma experimental ABIEncoderV2;
import "../interfaces/IAssetProxyDispatcher.sol";
contract MAssetProxyDispatcher is
IAssetProxyDispatcher
{
// Logs registration of new asset proxy
event AssetProxySet(
uint8 id,
address newAssetProxy,
address oldAssetProxy
);
/// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.
/// @param assetMetadata Byte array encoded for the respective asset proxy.
/// @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 assetMetadata,
address from,
address to,
uint256 amount
)
internal;
}

View File

@@ -1,117 +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.4.24;
pragma experimental ABIEncoderV2;
import "../libs/LibOrder.sol";
import "../libs/LibFillResults.sol";
import "../interfaces/IExchangeCore.sol";
contract MExchangeCore is
IExchangeCore
{
// Fill event is emitted whenever an order is filled.
event Fill(
address indexed makerAddress,
address takerAddress,
address indexed feeRecipientAddress,
uint256 makerAssetFilledAmount,
uint256 takerAssetFilledAmount,
uint256 makerFeePaid,
uint256 takerFeePaid,
bytes32 indexed orderHash,
bytes makerAssetData,
bytes takerAssetData
);
// Cancel event is emitted whenever an individual order is cancelled.
event Cancel(
address indexed makerAddress,
address indexed feeRecipientAddress,
bytes32 indexed orderHash,
bytes makerAssetData,
bytes takerAssetData
);
// CancelUpTo event is emitted whenever `cancelOrdersUpTo` is executed succesfully.
event CancelUpTo(
address indexed makerAddress,
uint256 makerEpoch
);
/// @dev Validates context for fillOrder. Succeeds or throws.
/// @param order to be filled.
/// @param orderStatus Status of order to be filled.
/// @param orderHash Hash of order to be filled.
/// @param takerAddress Address of order taker.
/// @param orderTakerAssetFilledAmount Amount of order already filled.
/// @param takerAssetFillAmount Desired amount of order to fill by taker.
/// @param signature Proof that the orders was created by its maker.
function assertValidFill(
LibOrder.Order memory order,
uint8 orderStatus,
bytes32 orderHash,
address takerAddress,
uint256 orderTakerAssetFilledAmount,
uint256 takerAssetFillAmount,
bytes memory signature
)
internal;
/// @dev Updates state with results of a fill order.
/// @param order that was filled.
/// @param takerAddress Address of taker who filled the order.
/// @param orderTakerAssetFilledAmount Amount of order already filled.
/// @return fillResults Amounts filled and fees paid by maker and taker.
function updateFilledState(
LibOrder.Order memory order,
address takerAddress,
bytes32 orderHash,
uint256 orderTakerAssetFilledAmount,
LibFillResults.FillResults memory fillResults
)
internal;
/// @dev Validates context for cancelOrder. Succeeds or throws.
/// @param order that was cancelled.
/// @param orderStatus Status of order that was cancelled.
/// @param orderHash Hash of order that was cancelled.
function assertValidCancel(
LibOrder.Order memory order,
uint8 orderStatus,
bytes32 orderHash
)
internal;
/// @dev Updates state with results of cancelling an order.
/// State is only updated if the order is currently fillable.
/// Otherwise, updating state would have no effect.
/// @param order that was cancelled.
/// @param orderStatus Status of order that was cancelled.
/// @param orderHash Hash of order that was cancelled.
/// @return stateUpdated Returns true only if state was updated.
function updateCancelledState(
LibOrder.Order memory order,
uint8 orderStatus,
bytes32 orderHash
)
internal
returns (bool stateUpdated);
}

View File

@@ -1,65 +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.4.24;
pragma experimental ABIEncoderV2;
import "../libs/LibOrder.sol";
import "../libs/LibFillResults.sol";
import "./MExchangeCore.sol";
import "../interfaces/IMatchOrders.sol";
contract MMatchOrders is
IMatchOrders
{
/// @dev Validates context for matchOrders. Succeeds or throws.
/// @param leftOrder First order to match.
/// @param rightOrder Second order to match.
function assertValidMatch(
LibOrder.Order memory leftOrder,
LibOrder.Order memory rightOrder
)
internal;
/// @dev Validates matched fill results. Succeeds or throws.
/// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.
function assertValidMatchResults(LibFillResults.MatchedFillResults memory matchedFillResults)
internal;
/// @dev Calculates fill amounts for the matched orders.
/// Each order is filled at their respective price point. However, the calculations are
/// carried out as though the orders are both being filled at the right order's price point.
/// The profit made by the leftOrder order goes to the taker (who matched the two orders).
/// @param leftOrder First order to match.
/// @param rightOrder Second order to match.
/// @param leftOrderStatus Order status of left order.
/// @param rightOrderStatus Order status of right order.
/// @param leftOrderFilledAmount Amount of left order already filled.
/// @param rightOrderFilledAmount Amount of right order already filled.
/// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.
function calculateMatchedFillResults(
LibOrder.Order memory leftOrder,
LibOrder.Order memory rightOrder,
uint8 leftOrderStatus,
uint8 rightOrderStatus,
uint256 leftOrderFilledAmount,
uint256 rightOrderFilledAmount
)
internal
returns (LibFillResults.MatchedFillResults memory matchedFillResults);
}

View File

@@ -1,50 +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.4.24;
import "../libs/LibOrder.sol";
import "./MMatchOrders.sol";
import "../libs/LibFillResults.sol";
contract MSettlement {
/// @dev Settles an order by transferring assets between counterparties.
/// @param order Order struct containing order specifications.
/// @param takerAddress Address selling takerAsset and buying makerAsset.
/// @param fillResults Amounts to be filled and fees paid by maker and taker.
function settleOrder(
LibOrder.Order memory order,
address takerAddress,
LibFillResults.FillResults memory fillResults
)
internal;
/// @dev Settles matched order by transferring appropriate funds between order makers, taker, and fee recipient.
/// @param leftOrder First matched order.
/// @param rightOrder Second matched order.
/// @param takerAddress Address that matched the orders. The taker receives the spread between orders as profit.
/// @param matchedFillResults Struct holding amounts to transfer between makers, taker, and fee recipients.
function settleMatchedOrders(
LibOrder.Order memory leftOrder,
LibOrder.Order memory rightOrder,
address takerAddress,
LibFillResults.MatchedFillResults memory matchedFillResults
)
internal;
}

View File

@@ -1,52 +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.4.24;
import "../interfaces/ISignatureValidator.sol";
contract MSignatureValidator is
ISignatureValidator
{
// Allowed signature types.
enum SignatureType {
Illegal, // 0x00, default value
Invalid, // 0x01
EIP712, // 0x02
EthSign, // 0x03
Caller, // 0x04
Wallet, // 0x05
Validator, // 0x06
PreSigned, // 0x07
Trezor // 0x08
}
/// @dev Verifies that a signature is valid.
/// @param hash Message hash that is signed.
/// @param signer Address of signer.
/// @param signature Proof of signing.
/// @return Validity of order signature.
function isValidSignature(
bytes32 hash,
address signer,
bytes memory signature
)
internal
view
returns (bool isValid);
}

View File

@@ -1,35 +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.4.24;
import "../interfaces/ITransactions.sol";
contract MTransactions is
ITransactions
{
/// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`).
/// If calling a fill function, this address will represent the taker.
/// If calling a cancel function, this address will represent the maker.
/// @return Signer of 0x transaction if entry point is `executeTransaction`.
/// `msg.sender` if entry point is any other function.
function getCurrentContextAddress()
internal
view
returns (address);
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
Copyright 2017 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
pragma solidity ^0.4.11;
import { Ownable_v1 as Ownable } from "../Ownable/Ownable_v1.sol";
import { Ownable_v1 as Ownable } from "../../../previous/Ownable/Ownable_v1.sol";
/// @title Token Registry - Stores metadata associated with ERC20 tokens. See ERC22 https://github.com/ethereum/EIPs/issues/22
/// @author Amir Bandeali - <amir@0xProject.com>, Will Warren - <will@0xProject.com>

View File

@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
Copyright 2017 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,12 +18,12 @@
pragma solidity ^0.4.11;
import { Token_v1 as Token } from "../Token/Token_v1.sol";
import { Ownable_v1 as Ownable } from "../Ownable/Ownable_v1.sol";
import { Token_v1 as Token } from "../../../previous/Token/Token_v1.sol";
import { Ownable_v1 as Ownable } from "../../../previous/Ownable/Ownable_v1.sol";
/// @title TokenTransferProxy - Transfers tokens on behalf of contracts that have been approved via decentralized governance.
/// @author Amir Bandeali - <amir@0xProject.com>, Will Warren - <will@0xProject.com>
contract TokenTransferProxy_v1 is Ownable {
contract TokenTransferProxy is Ownable {
/// @dev Only authorized addresses can invoke functions with this modifier.
modifier onlyAuthorized {

View File

@@ -1,56 +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.4.24;
pragma experimental ABIEncoderV2;
import "../Mintable/Mintable.sol";
import "../../utils/Ownable/Ownable.sol";
contract DummyERC20Token is Mintable, Ownable {
string public name;
string public symbol;
uint256 public decimals;
constructor (
string _name,
string _symbol,
uint256 _decimals,
uint256 _totalSupply)
public
{
name = _name;
symbol = _symbol;
decimals = _decimals;
totalSupply = _totalSupply;
balances[msg.sender] = _totalSupply;
}
function setBalance(address _target, uint256 _value)
public
onlyOwner
{
uint256 currBalance = balanceOf(_target);
if (_value < currBalance) {
totalSupply = safeSub(totalSupply, safeSub(currBalance, _value));
} else {
totalSupply = safeAdd(totalSupply, safeSub(_value, currBalance));
}
balances[_target] = _value;
}
}

View File

@@ -1,58 +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.4.24;
pragma experimental ABIEncoderV2;
import "../../tokens/ERC721Token/ERC721Token.sol";
import "../../utils/Ownable/Ownable.sol";
contract DummyERC721Token is
Ownable,
ERC721Token
{
/**
* @dev Constructor passes its arguments to the base ERC721Token constructor
* @param name of token
* @param symbol of token
*/
constructor (
string name,
string symbol)
public
ERC721Token(name, symbol)
{}
/**
* @dev Function to mint a new token
* @dev Reverts if the given token ID already exists
* @param to address the beneficiary that will own the minted token
* @param tokenId uint256 ID of the token to be minted by the msg.sender
*/
function mint(address to, uint256 tokenId)
public
onlyOwner
{
require(
!exists(tokenId),
"Token with tokenId already exists."
);
_mint(to, tokenId);
}
}

View File

@@ -0,0 +1,37 @@
pragma solidity ^0.4.18;
import { Mintable } from "../Mintable/Mintable.sol";
import { Ownable } from "../../utils/Ownable/Ownable.sol";
contract DummyToken is Mintable, Ownable {
string public name;
string public symbol;
uint public decimals;
function DummyToken(
string _name,
string _symbol,
uint _decimals,
uint _totalSupply)
public
{
name = _name;
symbol = _symbol;
decimals = _decimals;
totalSupply = _totalSupply;
balances[msg.sender] = _totalSupply;
}
function setBalance(address _target, uint _value)
public
onlyOwner
{
uint currBalance = balanceOf(_target);
if (_value < currBalance) {
totalSupply = safeSub(totalSupply, safeSub(currBalance, _value));
} else {
totalSupply = safeAdd(totalSupply, safeSub(_value, currBalance));
}
balances[_target] = _value;
}
}

View File

@@ -0,0 +1,31 @@
pragma solidity ^0.4.18;
import { ERC20Token } from "../../tokens/ERC20Token/ERC20Token.sol";
contract MaliciousToken is ERC20Token {
uint8 stateToUpdate = 1; // Not null so that change only requires 5000 gas
function updateState()
internal
{
stateToUpdate++;
}
function balanceOf(address _owner)
public
constant
returns (uint)
{
updateState();
return balances[_owner];
}
function allowance(address _owner, address _spender)
public
constant
returns (uint)
{
updateState();
return allowed[_owner][_spender];
}
}

View File

@@ -1,39 +1,17 @@
/*
pragma solidity ^0.4.18;
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.4.24;
pragma experimental ABIEncoderV2;
import "../../tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol";
import "../../utils/SafeMath/SafeMath.sol";
import { UnlimitedAllowanceToken } from "../../tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol";
import { SafeMath } from "../../utils/SafeMath/SafeMath.sol";
/*
* Mintable
* Base contract that creates a mintable UnlimitedAllowanceToken
*/
contract Mintable is UnlimitedAllowanceToken, SafeMath {
function mint(uint256 _value)
function mint(uint _value)
public
{
require(
_value <= 100000000000000000000,
"Minting more than 100000000000000000000 is not allowed."
);
require(_value <= 100000000000000000000);
balances[msg.sender] = safeAdd(_value, balances[msg.sender]);
totalSupply = safeAdd(totalSupply, _value);
}

View File

@@ -1,34 +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.4.24;
pragma experimental ABIEncoderV2;
import "../../protocol/Exchange/MixinAssetProxyDispatcher.sol";
contract TestAssetProxyDispatcher is MixinAssetProxyDispatcher {
function publicDispatchTransferFrom(
bytes memory assetMetadata,
address from,
address to,
uint256 amount)
public
{
dispatchTransferFrom(assetMetadata, from, to, amount);
}
}

View File

@@ -1,169 +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.4.24;
pragma experimental ABIEncoderV2;
import "../../utils/LibBytes/LibBytes.sol";
contract TestLibBytes is
LibBytes
{
/// @dev Pops the last byte off of a byte array by modifying its length.
/// @param b Byte array that will be modified.
/// @return The byte that was popped off.
function publicPopByte(bytes memory b)
public
pure
returns (bytes memory, bytes1 result)
{
result = popByte(b);
return (b, result);
}
/// @dev Pops the last 20 bytes off of a byte array by modifying its length.
/// @param b Byte array that will be modified.
/// @return The 20 byte address that was popped off.
function publicPopAddress(bytes memory b)
public
pure
returns (bytes memory, address result)
{
result = popAddress(b);
return (b, result);
}
/// @dev Tests equality of two byte arrays.
/// @param lhs First byte array to compare.
/// @param rhs Second byte array to compare.
/// @return True if arrays are the same. False otherwise.
function publicAreBytesEqual(bytes memory lhs, bytes memory rhs)
public
pure
returns (bool equal)
{
equal = areBytesEqual(lhs, rhs);
return equal;
}
/// @dev Reads an address from a position in a byte array.
/// @param b Byte array containing an address.
/// @param index Index in byte array of address.
/// @return address from byte array.
function publicReadAddress(
bytes memory b,
uint256 index)
public
pure
returns (address result)
{
result = readAddress(b, index);
return result;
}
/// @dev Writes an address into a specific position in a byte array.
/// @param b Byte array to insert address into.
/// @param index Index in byte array of address.
/// @param input Address to put into byte array.
function publicWriteAddress(
bytes memory b,
uint256 index,
address input)
public
pure
returns (bytes memory)
{
writeAddress(b, index, input);
return b;
}
/// @dev Reads a bytes32 value from a position in a byte array.
/// @param b Byte array containing a bytes32 value.
/// @param index Index in byte array of bytes32 value.
/// @return bytes32 value from byte array.
function publicReadBytes32(
bytes memory b,
uint256 index)
public
pure
returns (bytes32 result)
{
result = readBytes32(b, index);
return result;
}
/// @dev Writes a bytes32 into a specific position in a byte array.
/// @param b Byte array to insert <input> into.
/// @param index Index in byte array of <input>.
/// @param input bytes32 to put into byte array.
function publicWriteBytes32(
bytes memory b,
uint256 index,
bytes32 input)
public
pure
returns (bytes memory)
{
writeBytes32(b, index, input);
return b;
}
/// @dev Reads a uint256 value from a position in a byte array.
/// @param b Byte array containing a uint256 value.
/// @param index Index in byte array of uint256 value.
/// @return uint256 value from byte array.
function publicReadUint256(
bytes memory b,
uint256 index)
public
pure
returns (uint256 result)
{
result = readUint256(b, index);
return result;
}
/// @dev Writes a uint256 into a specific position in a byte array.
/// @param b Byte array to insert <input> into.
/// @param index Index in byte array of <input>.
/// @param input uint256 to put into byte array.
function publicWriteUint256(
bytes memory b,
uint256 index,
uint256 input)
public
pure
returns (bytes memory)
{
writeUint256(b, index, input);
return b;
}
/// @dev Reads the first 4 bytes from a byte array of arbitrary length.
/// @param b Byte array to read first 4 bytes from.
/// @return First 4 bytes of data.
function publicReadFirst4(bytes memory b)
public
pure
returns (bytes4 result)
{
result = readFirst4(b);
return result;
}
}

View File

@@ -1,96 +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.4.24;
pragma experimental ABIEncoderV2;
import "../../protocol/Exchange/libs/LibMath.sol";
import "../../protocol/Exchange/libs/LibOrder.sol";
import "../../protocol/Exchange/libs/LibFillResults.sol";
contract TestLibs is
LibMath,
LibOrder,
LibFillResults
{
function publicGetPartialAmount(
uint256 numerator,
uint256 denominator,
uint256 target)
public
pure
returns (uint256 partialAmount)
{
partialAmount = getPartialAmount(
numerator,
denominator,
target
);
return partialAmount;
}
function publicIsRoundingError(
uint256 numerator,
uint256 denominator,
uint256 target)
public
pure
returns (bool isError)
{
isError = isRoundingError(
numerator,
denominator,
target
);
return isError;
}
function publicGetOrderHash(Order memory order)
public
view
returns (bytes32 orderHash)
{
orderHash = getOrderHash(order);
return orderHash;
}
function getOrderSchemaHash()
public
view
returns (bytes32)
{
return ORDER_SCHEMA_HASH;
}
function getDomainSeparatorSchemaHash()
public
view
returns (bytes32)
{
return DOMAIN_SEPARATOR_SCHEMA_HASH;
}
function publicAddFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)
public
pure
returns (FillResults memory)
{
addFillResults(totalFillResults, singleFillResults);
return totalFillResults;
}
}

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.4.24;
pragma experimental ABIEncoderV2;
import "../../protocol/Exchange/MixinSignatureValidator.sol";
import "../../protocol/Exchange/MixinTransactions.sol";
contract TestSignatureValidator is
MixinSignatureValidator,
MixinTransactions
{
function publicIsValidSignature(
bytes32 hash,
address signer,
bytes memory signature
)
public
view
returns (bool isValid)
{
isValid = isValidSignature(
hash,
signer,
signature
);
return isValid;
}
}

View File

@@ -1,133 +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.4.23;
pragma experimental ABIEncoderV2;
import "../../protocol/Exchange/interfaces/IExchange.sol";
import "../../protocol/Exchange/libs/LibOrder.sol";
import "../../utils/Ownable/Ownable.sol";
contract Whitelist is
Ownable
{
// Revert reasons
string constant MAKER_NOT_WHITELISTED = "Maker address not whitelisted.";
string constant TAKER_NOT_WHITELISTED = "Taker address not whitelisted.";
string constant INVALID_SENDER = "Sender must equal transaction origin.";
// Mapping of address => whitelist status.
mapping (address => bool) public isWhitelisted;
// Exchange contract.
IExchange EXCHANGE;
byte constant VALIDATOR_SIGNATURE_BYTE = "\x06";
bytes TX_ORIGIN_SIGNATURE;
constructor (address _exchange)
public
{
EXCHANGE = IExchange(_exchange);
TX_ORIGIN_SIGNATURE = abi.encodePacked(address(this), VALIDATOR_SIGNATURE_BYTE);
}
/// @dev Adds or removes an address from the whitelist.
/// @param target Address to add or remove from whitelist.
/// @param isApproved Whitelist status to assign to address.
function updateWhitelistStatus(
address target,
bool isApproved
)
external
onlyOwner
{
isWhitelisted[target] = isApproved;
}
/// @dev Fills an order using `msg.sender` as the taker.
/// The transaction will revert if both the maker and taker are not whitelisted.
/// Orders should specify this contract as the `senderAddress` in order to gaurantee
/// that both maker and taker have been whitelisted.
/// @param order Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param salt Arbitrary value to gaurantee uniqueness of 0x transaction hash.
/// @param orderSignature Proof that order has been created by maker.
function fillOrderIfWhitelisted(
LibOrder.Order memory order,
uint256 takerAssetFillAmount,
uint256 salt,
bytes memory orderSignature
)
public
{
address takerAddress = msg.sender;
// This contract must be the entry point for the transaction.
require(
takerAddress == tx.origin,
INVALID_SENDER
);
// Check if maker is on the whitelist.
require(
isWhitelisted[order.makerAddress],
MAKER_NOT_WHITELISTED
);
// Check if taker is on the whitelist.
require(
isWhitelisted[takerAddress],
TAKER_NOT_WHITELISTED
);
// Encode arguments into byte array.
bytes memory data = abi.encodeWithSelector(
EXCHANGE.fillOrder.selector,
order,
takerAssetFillAmount,
orderSignature
);
// Call `fillOrder` via `executeTransaction`.
EXCHANGE.executeTransaction(
salt,
takerAddress,
data,
TX_ORIGIN_SIGNATURE
);
}
/// @dev Verifies signer is same as signer of current Ethereum transaction.
/// NOTE: This function can currently be used to validate signatures coming from outside of this contract.
/// Extra safety checks can be added for a production contract.
/// @param signer Address that should have signed the given hash.
/// @param signature Proof of signing.
/// @return Validity of order signature.
function isValidSignature(
bytes32 hash,
address signer,
bytes signature
)
external
view
returns (bool isValid)
{
return signer == tx.origin;
}
}

View File

@@ -1,90 +1,45 @@
/*
pragma solidity ^0.4.18;
Copyright 2018 ZeroEx Intl.
import { Token } from "../Token/Token.sol";
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
contract ERC20Token is Token {
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.4.24;
pragma experimental ABIEncoderV2;
import "./IERC20Token.sol";
contract ERC20Token is IERC20Token {
string constant INSUFFICIENT_BALANCE = "Insufficient balance to complete transfer.";
string constant INSUFFICIENT_ALLOWANCE = "Insufficient allowance to complete transfer.";
string constant OVERFLOW = "Transfer would result in an overflow.";
mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed;
uint256 public totalSupply;
function transfer(address _to, uint256 _value)
function transfer(address _to, uint _value)
public
returns (bool)
{
require(
balances[msg.sender] >= _value,
INSUFFICIENT_BALANCE
);
require(
balances[_to] + _value >= balances[_to],
OVERFLOW
);
require(balances[msg.sender] >= _value && balances[_to] + _value >= balances[_to]);
balances[msg.sender] -= _value;
balances[_to] += _value;
emit Transfer(msg.sender, _to, _value);
Transfer(msg.sender, _to, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value)
function transferFrom(address _from, address _to, uint _value)
public
returns (bool)
{
require(
balances[_from] >= _value,
INSUFFICIENT_BALANCE
);
require(
allowed[_from][msg.sender] >= _value,
INSUFFICIENT_ALLOWANCE
);
require(
balances[_to] + _value >= balances[_to],
OVERFLOW
);
require(balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value >= balances[_to]);
balances[_to] += _value;
balances[_from] -= _value;
allowed[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
Transfer(_from, _to, _value);
return true;
}
function approve(address _spender, uint256 _value)
function approve(address _spender, uint _value)
public
returns (bool)
{
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
Approval(msg.sender, _spender, _value);
return true;
}
function balanceOf(address _owner)
public view
returns (uint256)
public
view
returns (uint)
{
return balances[_owner];
}
@@ -92,9 +47,12 @@ contract ERC20Token is IERC20Token {
function allowance(address _owner, address _spender)
public
view
returns (uint256)
returns (uint)
{
return allowed[_owner][_spender];
}
}
mapping (address => uint) balances;
mapping (address => mapping (address => uint)) allowed;
uint public totalSupply;
}

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