Compare commits
143 Commits
@0xproject
...
@0xproject
Author | SHA1 | Date | |
---|---|---|---|
|
f5c74d123a | ||
|
c8421efcd3 | ||
|
f382609d01 | ||
|
f9615c18a1 | ||
|
d50fbac5f9 | ||
|
d3c64bd5b4 | ||
|
7024a7468a | ||
|
62e60e2ba6 | ||
|
fb3860757c | ||
|
e4a8b17522 | ||
|
448df1bb9c | ||
|
bf6900fb2a | ||
|
50552546f3 | ||
|
324fab8186 | ||
|
7ab80f01b5 | ||
|
9ce4a5c7b1 | ||
|
c9a0525a10 | ||
|
83465bb7f5 | ||
|
e8771fb36a | ||
|
d4d03f3d7f | ||
|
d567d667e8 | ||
|
3d55bbbc29 | ||
|
2f8e52f905 | ||
|
a5896ac6b6 | ||
|
94b9d5644c | ||
|
06e5fc233c | ||
|
aefb922a05 | ||
|
a22434fd73 | ||
|
c41846805d | ||
|
b7b45b69a6 | ||
|
ed5528664c | ||
|
fe88d3c225 | ||
|
aed4ee8694 | ||
|
df9cfe7840 | ||
|
8cd4578d83 | ||
|
9ca41b9536 | ||
|
559743c911 | ||
|
04a0eae241 | ||
|
0500d2fb6e | ||
|
31f1a9e5aa | ||
|
6387aae471 | ||
|
152082e182 | ||
|
08eb2b3df7 | ||
|
846ec87249 | ||
|
62690b5159 | ||
|
719c432ca8 | ||
|
e654616b6d | ||
|
f0473b0320 | ||
|
fcc627e6e1 | ||
|
fe17802cd2 | ||
|
384c05ccc7 | ||
|
193e4f3275 | ||
|
6fd87568e7 | ||
|
484fd68495 | ||
|
792be54443 | ||
|
00df102c29 | ||
|
90e68ddd73 | ||
|
df27f4f118 | ||
|
bee26daf0c | ||
|
b76c738785 | ||
|
8ca9fb0251 | ||
|
3b26a656f7 | ||
|
2f5ac5d993 | ||
|
a2fc9a964b | ||
|
b8a267370d | ||
|
fa3d011f68 | ||
|
a7fc9caacb | ||
|
c284f6dcd4 | ||
|
368d59c3ca | ||
|
94ee82e076 | ||
|
bfefb6e696 | ||
|
95b7601e2b | ||
|
f9c8bd868c | ||
|
a773973b1b | ||
|
a60006366b | ||
|
a66bb7889a | ||
|
adfba06e85 | ||
|
6ee4e954f6 | ||
|
a11d139ff6 | ||
|
85a3e66314 | ||
|
1a3958ed60 | ||
|
743c957918 | ||
|
224a6c192b | ||
|
ae47da3801 | ||
|
a6d669453f | ||
|
0beab9eec4 | ||
|
aa997f1be5 | ||
|
4eb58a70bb | ||
|
5b31d0aa36 | ||
|
79e7c44884 | ||
|
1382c1243a | ||
|
8f2fd9b603 | ||
|
d625b65a09 | ||
|
101e9be7b9 | ||
|
9f93d8f533 | ||
|
6050a59e4a | ||
|
e5b7e29113 | ||
|
ecdd0ce9f2 | ||
|
fc5c598f8f | ||
|
18ebed3c5d | ||
|
822e319efe | ||
|
6d462fc961 | ||
|
4b71c65aea | ||
|
34ab53173d | ||
|
d6be6f79ce | ||
|
87d36f06fd | ||
|
3eb05b4505 | ||
|
0789c6a3d8 | ||
|
b587f076fe | ||
|
a5a7217c8f | ||
|
c0cf55b40b | ||
|
9200ed2216 | ||
|
e1f7dd1372 | ||
|
32833b7301 | ||
|
3302c89284 | ||
|
e18d61b31a | ||
|
61cd1ae525 | ||
|
064608a8ef | ||
|
5a840c88b5 | ||
|
b14c3fe48d | ||
|
4874d55d03 | ||
|
b20e40dd6f | ||
|
bc28a08dd0 | ||
|
0d3010f6fc | ||
|
399a651fa3 | ||
|
30ac5fcb5e | ||
|
92cb5e10be | ||
|
10faa47495 | ||
|
f0bbf2cab0 | ||
|
338e8be327 | ||
|
d4a366aeb1 | ||
|
dea322e2c5 | ||
|
790af0fd72 | ||
|
39008372e5 | ||
|
1026952f26 | ||
|
9631927a8c | ||
|
b0e6ce581a | ||
|
e575323c60 | ||
|
809ac3340c | ||
|
f0af638874 | ||
|
b49148ec54 | ||
|
4e5bfae332 | ||
|
662dc12877 |
@@ -3,7 +3,7 @@ version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
- image: circleci/node:9
|
||||
environment:
|
||||
CONTRACTS_COMMIT_HASH: '9ed05f5'
|
||||
working_directory: ~/repo
|
||||
@@ -11,91 +11,68 @@ jobs:
|
||||
- checkout
|
||||
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
|
||||
- restore_cache:
|
||||
key: dependency-cache-{{ checksum "package.json" }}
|
||||
name: Restore Yarn Package Cache
|
||||
keys:
|
||||
- yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
|
||||
- yarn-packages-{{ .Branch }}
|
||||
- yarn-packages-master
|
||||
- yarn-packages-
|
||||
- run:
|
||||
name: yarn
|
||||
command: yarn --frozen-lockfile
|
||||
command: yarn --frozen-lockfile install
|
||||
- save_cache:
|
||||
key: dependency-cache-{{ checksum "package.json" }}
|
||||
name: Save Yarn Package Cache
|
||||
key: yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- run: wget https://s3.amazonaws.com/testrpc-shapshots/${CONTRACTS_COMMIT_HASH}.zip
|
||||
- run: unzip ${CONTRACTS_COMMIT_HASH}.zip -d testrpc_snapshot
|
||||
- node_modules/
|
||||
- run: node ./node_modules/lerna/bin/lerna.js bootstrap
|
||||
- run: yarn build
|
||||
- save_cache:
|
||||
key: repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo
|
||||
test-installation:
|
||||
test-1:
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
- image: circleci/node:9
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn test:installation
|
||||
test-0xjs:
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
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-0xjs-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/0x.js/coverage/lcov.info
|
||||
test-contracts:
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
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 contracts
|
||||
test-sol-compiler:
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
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 @0xproject/contract-wrappers
|
||||
- run: yarn wsrun test:circleci @0xproject/sol-compiler
|
||||
- save_cache:
|
||||
key: coverage-contract-wrappers-{{ .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
|
||||
test-rest:
|
||||
test-contracts:
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
- 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
|
||||
- run: yarn wsrun test:circleci contracts
|
||||
test-2:
|
||||
docker:
|
||||
- image: circleci/node:9
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- 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
|
||||
- save_cache:
|
||||
key: coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
@@ -124,27 +101,19 @@ jobs:
|
||||
key: coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/metacoin/coverage/lcov.info
|
||||
lint:
|
||||
static-tests:
|
||||
working_directory: ~/repo
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn lerna:run lint
|
||||
prettier:
|
||||
working_directory: ~/repo
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
- image: circleci/node:9
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn prettier:ci
|
||||
- run: yarn lerna:run lint
|
||||
submit-coverage:
|
||||
docker:
|
||||
- image: circleci/node:6.12
|
||||
- image: circleci/node:9
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- restore_cache:
|
||||
@@ -156,6 +125,9 @@ jobs:
|
||||
- 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 }}
|
||||
@@ -168,6 +140,9 @@ 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 }}
|
||||
@@ -183,29 +158,19 @@ workflows:
|
||||
main:
|
||||
jobs:
|
||||
- build
|
||||
# - test-installation:
|
||||
# requires:
|
||||
# - build
|
||||
- test-0xjs:
|
||||
- test-1:
|
||||
requires:
|
||||
- build
|
||||
- test-2:
|
||||
requires:
|
||||
- build
|
||||
- test-contracts:
|
||||
requires:
|
||||
- build
|
||||
- test-sol-compiler:
|
||||
requires:
|
||||
- build
|
||||
- test-rest:
|
||||
requires:
|
||||
- build
|
||||
- prettier:
|
||||
requires:
|
||||
- build
|
||||
- lint:
|
||||
- static-tests:
|
||||
requires:
|
||||
- build
|
||||
- submit-coverage:
|
||||
requires:
|
||||
- test-0xjs
|
||||
- test-sol-compiler
|
||||
- test-rest
|
||||
- test-1
|
||||
- test-2
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -86,6 +86,7 @@ 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/order-utils/src/generated_contract_wrappers/
|
||||
packages/migrations/src/v1/contract_wrappers
|
||||
packages/migrations/src/v2/contract_wrappers
|
||||
|
||||
|
15
package.json
15
package.json
@@ -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,11 +23,14 @@
|
||||
"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"
|
||||
"lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing",
|
||||
"comment:postinstall": "HACK: For some reason `yarn` is not setting up symlinks properly for order-utils. We temporarily set them manually. Remove this after V2 refactor is complete.",
|
||||
"postinstall": "rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -f `pwd`/packages/contracts/node_modules/@0xproject/types; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types"
|
||||
},
|
||||
"config": {
|
||||
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
||||
@@ -35,10 +39,13 @@
|
||||
"async-child-process": "^1.1.1",
|
||||
"coveralls": "^3.0.0",
|
||||
"ganache-cli": "^6.1.0",
|
||||
"lcov-result-merger": "^2.0.0",
|
||||
"lcov-result-merger": "^3.0.0",
|
||||
"lerna": "^2.5.1",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"prettier": "^1.11.1",
|
||||
"wsrun": "^2.2.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"ethereumjs-tx": "0xProject/ethereumjs-tx#fake-tx-include-signature-by-default"
|
||||
}
|
||||
}
|
||||
|
@@ -44,6 +44,7 @@
|
||||
"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",
|
||||
@@ -101,13 +102,14 @@
|
||||
"@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-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"
|
||||
},
|
||||
|
@@ -11,7 +11,7 @@ before('migrate contracts', async function(): Promise<void> {
|
||||
const mochaTestTimeoutMs = 20000;
|
||||
this.timeout(mochaTestTimeoutMs);
|
||||
const txDefaults = {
|
||||
gas: devConstants.GAS_ESTIMATE,
|
||||
gas: devConstants.GAS_LIMIT,
|
||||
from: devConstants.TESTRPC_FIRST_ADDRESS,
|
||||
};
|
||||
const artifactsDir = `../migrations/artifacts/1.0.0`;
|
||||
|
@@ -27,9 +27,9 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
|
||||
"dependencies": {
|
||||
"@0xproject/types": "^0.7.0",
|
||||
"@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",
|
||||
|
@@ -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';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { EventAbi, MethodAbi } from '@0xproject/types';
|
||||
import { EventAbi, MethodAbi } from 'ethereum-types';
|
||||
|
||||
export enum ParamKind {
|
||||
Input = 'input',
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { AbiType, ConstructorAbi, DataItem } from '@0xproject/types';
|
||||
import { AbiType, ConstructorAbi, DataItem } from 'ethereum-types';
|
||||
import * as fs from 'fs';
|
||||
import * as _ from 'lodash';
|
||||
import * as path from 'path';
|
||||
|
@@ -42,7 +42,7 @@
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/types": "^0.7.0",
|
||||
"ethereum-types": "^0.0.1",
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"@0xproject/web3-wrapper": "^0.6.4",
|
||||
|
@@ -1,3 +1,5 @@
|
||||
import { abiUtils, BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import {
|
||||
AbiDefinition,
|
||||
AbiType,
|
||||
@@ -8,9 +10,7 @@ import {
|
||||
Provider,
|
||||
TxData,
|
||||
TxDataPayable,
|
||||
} from '@0xproject/types';
|
||||
import { abiUtils, BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
} from 'ethereum-types';
|
||||
import * as ethers from 'ethers';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DataItem } from '@0xproject/types';
|
||||
import { DataItem } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
// tslint:disable-next-line:completed-docs
|
||||
|
@@ -80,11 +80,12 @@
|
||||
"@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/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",
|
||||
|
@@ -11,7 +11,7 @@ before('migrate contracts', async function(): Promise<void> {
|
||||
const mochaTestTimeoutMs = 20000;
|
||||
this.timeout(mochaTestTimeoutMs);
|
||||
const txDefaults = {
|
||||
gas: devConstants.GAS_ESTIMATE,
|
||||
gas: devConstants.GAS_LIMIT,
|
||||
from: devConstants.TESTRPC_FIRST_ADDRESS,
|
||||
};
|
||||
const artifactsDir = `../migrations/artifacts/1.0.0`;
|
||||
|
@@ -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
|
||||
// tslint:disable:no-consecutive-blank-lines ordered-imports
|
||||
// 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, MethodAbi, Provider, TxData, TxDataPayable } from '@0xproject/types';
|
||||
import { BlockParam, BlockParamLiteral, CallData, ContractAbi, DataItem, DecodedLogArgs, MethodAbi, Provider, TxData, TxDataPayable } from 'ethereum-types';
|
||||
import { BigNumber, classUtils, logUtils, promisify } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as ethers from 'ethers';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
export interface {{name}}ContractEventArgs {
|
||||
export interface {{name}}ContractEventArgs extends DecodedLogArgs {
|
||||
{{#each inputs}}
|
||||
{{name}}: {{#returnType type components}}{{/returnType}};
|
||||
{{/each}}
|
||||
|
@@ -33,6 +33,7 @@
|
||||
"TestLibs",
|
||||
"TestSignatureValidator",
|
||||
"TokenRegistry",
|
||||
"Whitelist",
|
||||
"WETH9",
|
||||
"ZRXToken"
|
||||
]
|
||||
|
@@ -29,7 +29,7 @@
|
||||
"test:circleci": "yarn test"
|
||||
},
|
||||
"config": {
|
||||
"abis": "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock||TestAssetProxyDispatcher|TestLibBytes|TestLibs|TestSignatureValidator|TokenRegistry|WETH9|ZRXToken).json"
|
||||
"abis": "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|TestAssetProxyDispatcher|TestLibBytes|TestLibs|TestSignatureValidator|TokenRegistry|Whitelist|WETH9|ZRXToken).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -48,7 +48,9 @@
|
||||
"@0xproject/subproviders": "^0.10.1",
|
||||
"@0xproject/sol-cov": "^0.0.11",
|
||||
"@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",
|
||||
@@ -67,12 +69,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/base-contract": "^0.3.2",
|
||||
"@0xproject/order-utils": "^0.0.5",
|
||||
"@0xproject/order-utils": "^0.0.6",
|
||||
"@0xproject/sol-compiler": "^0.5.0",
|
||||
"@0xproject/types": "^0.7.0",
|
||||
"@0xproject/types": "^1.0.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",
|
||||
|
@@ -47,21 +47,25 @@ contract ERC20Proxy is
|
||||
bytes memory assetMetadata,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount)
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
// Data must be intended for this proxy.
|
||||
uint256 length = assetMetadata.length;
|
||||
|
||||
require(
|
||||
uint8(assetMetadata[0]) == PROXY_ID,
|
||||
length == 21,
|
||||
INVALID_METADATA_LENGTH
|
||||
);
|
||||
|
||||
require(
|
||||
uint8(assetMetadata[length - 1]) == PROXY_ID,
|
||||
PROXY_ID_MISMATCH
|
||||
);
|
||||
|
||||
// Decode metadata.
|
||||
require(
|
||||
assetMetadata.length == 21,
|
||||
INVALID_METADATA_LENGTH
|
||||
);
|
||||
address token = readAddress(assetMetadata, 1);
|
||||
address token = readAddress(assetMetadata, 0);
|
||||
|
||||
// Transfer tokens.
|
||||
bool success = IERC20Token(token).transferFrom(from, to, amount);
|
||||
|
@@ -47,12 +47,20 @@ contract ERC721Proxy is
|
||||
bytes memory assetMetadata,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount)
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
// Data must be intended for this proxy.
|
||||
uint256 length = assetMetadata.length;
|
||||
|
||||
require(
|
||||
uint8(assetMetadata[0]) == PROXY_ID,
|
||||
length == 53,
|
||||
INVALID_METADATA_LENGTH
|
||||
);
|
||||
|
||||
require(
|
||||
uint8(assetMetadata[length - 1]) == PROXY_ID,
|
||||
PROXY_ID_MISMATCH
|
||||
);
|
||||
|
||||
@@ -63,12 +71,8 @@ contract ERC721Proxy is
|
||||
);
|
||||
|
||||
// Decode metadata
|
||||
require(
|
||||
assetMetadata.length == 53,
|
||||
INVALID_METADATA_LENGTH
|
||||
);
|
||||
address token = readAddress(assetMetadata, 1);
|
||||
uint256 tokenId = readUint256(assetMetadata, 21);
|
||||
address token = readAddress(assetMetadata, 0);
|
||||
uint256 tokenId = readUint256(assetMetadata, 20);
|
||||
|
||||
// Transfer token.
|
||||
// Either succeeds or throws.
|
||||
|
@@ -36,7 +36,8 @@ contract MixinAssetProxy is
|
||||
bytes assetMetadata,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount)
|
||||
uint256 amount
|
||||
)
|
||||
external
|
||||
onlyAuthorized
|
||||
{
|
||||
@@ -57,7 +58,8 @@ contract MixinAssetProxy is
|
||||
bytes[] memory assetMetadata,
|
||||
address[] memory from,
|
||||
address[] memory to,
|
||||
uint256[] memory amounts)
|
||||
uint256[] memory amounts
|
||||
)
|
||||
public
|
||||
onlyAuthorized
|
||||
{
|
||||
|
@@ -87,7 +87,10 @@ contract MixinAuthorizable is
|
||||
/// @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)
|
||||
function removeAuthorizedAddressAtIndex(
|
||||
address target,
|
||||
uint256 index
|
||||
)
|
||||
external
|
||||
{
|
||||
require(
|
||||
|
@@ -34,7 +34,8 @@ contract IAssetProxy is
|
||||
bytes assetMetadata,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount)
|
||||
uint256 amount
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Makes multiple transfers of assets. Either succeeds or throws.
|
||||
@@ -46,7 +47,8 @@ contract IAssetProxy is
|
||||
bytes[] memory assetMetadata,
|
||||
address[] memory from,
|
||||
address[] memory to,
|
||||
uint256[] memory amounts)
|
||||
uint256[] memory amounts
|
||||
)
|
||||
public;
|
||||
|
||||
/// @dev Gets the proxy id associated with the proxy address.
|
||||
|
@@ -45,6 +45,9 @@ contract IAuthorizable is
|
||||
/// @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)
|
||||
function removeAuthorizedAddressAtIndex(
|
||||
address target,
|
||||
uint256 index
|
||||
)
|
||||
external;
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@ contract MAssetProxy is
|
||||
bytes memory assetMetadata,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount)
|
||||
uint256 amount
|
||||
)
|
||||
internal;
|
||||
}
|
||||
|
@@ -38,5 +38,5 @@ contract MAuthorizable is
|
||||
);
|
||||
|
||||
/// @dev Only authorized addresses can invoke functions with this modifier.
|
||||
modifier onlyAuthorized { _; }
|
||||
modifier onlyAuthorized { revert(); _; }
|
||||
}
|
||||
|
@@ -39,7 +39,8 @@ contract MixinAssetProxyDispatcher is
|
||||
function registerAssetProxy(
|
||||
uint8 assetProxyId,
|
||||
address newAssetProxy,
|
||||
address oldAssetProxy)
|
||||
address oldAssetProxy
|
||||
)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
@@ -86,17 +87,20 @@ contract MixinAssetProxyDispatcher is
|
||||
bytes memory assetMetadata,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount)
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
// Do nothing if no amount should be transferred.
|
||||
if (amount > 0) {
|
||||
|
||||
// Lookup asset proxy
|
||||
uint256 length = assetMetadata.length;
|
||||
require(
|
||||
assetMetadata.length >= 1,
|
||||
length > 0,
|
||||
GT_ZERO_LENGTH_REQUIRED
|
||||
);
|
||||
uint8 assetProxyId = uint8(assetMetadata[0]);
|
||||
uint8 assetProxyId = uint8(assetMetadata[length - 1]);
|
||||
IAssetProxy assetProxy = assetProxies[assetProxyId];
|
||||
|
||||
// transferFrom will either succeed or throw.
|
||||
|
@@ -19,18 +19,24 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "./mixins/MSignatureValidator.sol";
|
||||
import "./interfaces/ISigner.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
|
||||
MSignatureValidator,
|
||||
MTransactions
|
||||
{
|
||||
|
||||
// Mapping of hash => signer => signed
|
||||
mapping(bytes32 => mapping(address => bool)) preSigned;
|
||||
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.
|
||||
@@ -39,7 +45,8 @@ contract MixinSignatureValidator is
|
||||
function preSign(
|
||||
bytes32 hash,
|
||||
address signer,
|
||||
bytes signature)
|
||||
bytes signature
|
||||
)
|
||||
external
|
||||
{
|
||||
require(
|
||||
@@ -49,6 +56,19 @@ contract MixinSignatureValidator is
|
||||
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.
|
||||
@@ -57,71 +77,69 @@ contract MixinSignatureValidator is
|
||||
function isValidSignature(
|
||||
bytes32 hash,
|
||||
address signer,
|
||||
bytes memory signature)
|
||||
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
|
||||
);
|
||||
SignatureType signatureType = SignatureType(uint8(signature[0]));
|
||||
|
||||
// Variables are not scoped in Solidity
|
||||
// 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
|
||||
// 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) {
|
||||
// NOTE: Reason cannot be assigned to a variable because of https://github.com/ethereum/solidity/issues/4051
|
||||
revert("Illegal signature type.");
|
||||
revert(ILLEGAL_SIGNATURE_TYPE);
|
||||
|
||||
// Always invalid signature
|
||||
// Always invalid signature.
|
||||
// Like Illegal, this is always implicitly available and therefore
|
||||
// offered explicitly. It can be implicitly created by providing
|
||||
// a correctly formatted but incorrect signature.
|
||||
} else if (signatureType == SignatureType.Invalid) {
|
||||
require(
|
||||
signature.length == 1,
|
||||
signature.length == 0,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
isValid = false;
|
||||
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) {
|
||||
// Signature using EIP712
|
||||
} else if (signatureType == SignatureType.EIP712) {
|
||||
require(
|
||||
signature.length == 1,
|
||||
signature.length == 65,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
isValid = signer == msg.sender;
|
||||
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.Ecrecover) {
|
||||
} else if (signatureType == SignatureType.EthSign) {
|
||||
require(
|
||||
signature.length == 66,
|
||||
signature.length == 65,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
v = uint8(signature[1]);
|
||||
r = readBytes32(signature, 2);
|
||||
s = readBytes32(signature, 34);
|
||||
v = uint8(signature[0]);
|
||||
r = readBytes32(signature, 1);
|
||||
s = readBytes32(signature, 33);
|
||||
recovered = ecrecover(
|
||||
keccak256("\x19Ethereum Signed Message:\n32", hash),
|
||||
v,
|
||||
@@ -131,20 +149,55 @@ contract MixinSignatureValidator is
|
||||
isValid = signer == recovered;
|
||||
return isValid;
|
||||
|
||||
// Signature using EIP712
|
||||
} else if (signatureType == SignatureType.EIP712) {
|
||||
// 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 == 66,
|
||||
signature.length == 0,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
v = uint8(signature[1]);
|
||||
r = readBytes32(signature, 2);
|
||||
s = readBytes32(signature, 34);
|
||||
recovered = ecrecover(hash, v, r, s);
|
||||
isValid = signer == recovered;
|
||||
isValid = signer == msg.sender;
|
||||
return isValid;
|
||||
|
||||
// Signature from Trezor hardware wallet
|
||||
// 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).
|
||||
@@ -154,12 +207,12 @@ contract MixinSignatureValidator is
|
||||
// https://github.com/trezor/trezor-mcu/blob/master/firmware/crypto.c#L36
|
||||
} else if (signatureType == SignatureType.Trezor) {
|
||||
require(
|
||||
signature.length == 66,
|
||||
signature.length == 65,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
v = uint8(signature[1]);
|
||||
r = readBytes32(signature, 2);
|
||||
s = readBytes32(signature, 34);
|
||||
v = uint8(signature[0]);
|
||||
r = readBytes32(signature, 1);
|
||||
s = readBytes32(signature, 33);
|
||||
recovered = ecrecover(
|
||||
keccak256("\x19Ethereum Signed Message:\n\x41", hash),
|
||||
v,
|
||||
@@ -169,11 +222,6 @@ contract MixinSignatureValidator is
|
||||
isValid = signer == recovered;
|
||||
return isValid;
|
||||
|
||||
// Signature verified by signer contract
|
||||
} else if (signatureType == SignatureType.Contract) {
|
||||
isValid = ISigner(signer).isValidSignature(hash, signature);
|
||||
return isValid;
|
||||
|
||||
// Signer signed hash previously using the preSign function
|
||||
} else if (signatureType == SignatureType.PreSigned) {
|
||||
isValid = preSigned[hash][signer];
|
||||
@@ -185,7 +233,6 @@ contract MixinSignatureValidator is
|
||||
// that we currently support. In this case returning false
|
||||
// may lead the caller to incorrectly believe that the
|
||||
// signature was invalid.)
|
||||
// NOTE: Reason cannot be assigned to a variable because of https://github.com/ethereum/solidity/issues/4051
|
||||
revert("Unsupported signature type.");
|
||||
revert(UNSUPPORTED_SIGNATURE_TYPE);
|
||||
}
|
||||
}
|
||||
|
@@ -43,15 +43,20 @@ contract MixinTransactions is
|
||||
uint256 salt,
|
||||
address signer,
|
||||
bytes data,
|
||||
bytes signature)
|
||||
bytes signature
|
||||
)
|
||||
external
|
||||
{
|
||||
// Prevent reentrancy
|
||||
require(currentContextAddress == address(0));
|
||||
require(
|
||||
currentContextAddress == address(0),
|
||||
REENTRANCY_NOT_ALLOWED
|
||||
);
|
||||
|
||||
// Calculate transaction hash
|
||||
bytes32 transactionHash = keccak256(
|
||||
address(this),
|
||||
signer,
|
||||
salt,
|
||||
data
|
||||
);
|
||||
|
@@ -20,17 +20,15 @@ pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./IExchangeCore.sol";
|
||||
import "./IMatchOrders";
|
||||
import "./ISettlement";
|
||||
import "./ISignatureValidator";
|
||||
import "./ITransactions";
|
||||
import "./IAssetProxyDispatcher";
|
||||
import "./IWrapperFunctions";
|
||||
import "./IMatchOrders.sol";
|
||||
import "./ISignatureValidator.sol";
|
||||
import "./ITransactions.sol";
|
||||
import "./IAssetProxyDispatcher.sol";
|
||||
import "./IWrapperFunctions.sol";
|
||||
|
||||
contract IExchange is
|
||||
IExchangeCore,
|
||||
IMatchOrders,
|
||||
ISettlement,
|
||||
ISignatureValidator,
|
||||
ITransactions,
|
||||
IAssetProxyDispatcher,
|
||||
|
@@ -27,6 +27,16 @@ contract ISignatureValidator {
|
||||
function preSign(
|
||||
bytes32 hash,
|
||||
address signer,
|
||||
bytes signature)
|
||||
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;
|
||||
}
|
||||
|
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
|
||||
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);
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
contract ISigner {
|
||||
contract IWallet {
|
||||
|
||||
/// @dev Verifies that a signature is valid.
|
||||
/// @param hash Message hash that is signed.
|
||||
@@ -26,7 +26,8 @@ contract ISigner {
|
||||
/// @return Validity of order signature.
|
||||
function isValidSignature(
|
||||
bytes32 hash,
|
||||
bytes signature)
|
||||
bytes signature
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bool isValid);
|
@@ -19,27 +19,23 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./libs/LibOrder.sol";
|
||||
import "./libs/LibFillResults.sol";
|
||||
import "../libs/LibOrder.sol";
|
||||
import "../libs/LibFillResults.sol";
|
||||
|
||||
contract IWrapperFunctions is
|
||||
LibBytes,
|
||||
LibMath,
|
||||
LibOrder,
|
||||
LibFillResults,
|
||||
LibExchangeErrors,
|
||||
MExchangeCore
|
||||
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.LibOrder.Order memory order,
|
||||
LibOrder.Order memory order,
|
||||
uint256 takerAssetFillAmount,
|
||||
bytes memory signature)
|
||||
public
|
||||
returns (LibFillResults.LibFillResults.FillResults memory fillResults);
|
||||
returns (LibFillResults.FillResults memory fillResults);
|
||||
|
||||
/// @dev Fills an order with specified parameters and ECDSA signature.
|
||||
/// Returns false if the transaction would otherwise revert.
|
||||
|
@@ -32,6 +32,7 @@ contract LibExchangeErrors {
|
||||
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.";
|
||||
|
||||
|
@@ -41,6 +41,7 @@ contract MAssetProxyDispatcher is
|
||||
bytes memory assetMetadata,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount)
|
||||
uint256 amount
|
||||
)
|
||||
internal;
|
||||
}
|
||||
|
@@ -25,14 +25,15 @@ contract MSignatureValidator is
|
||||
{
|
||||
// Allowed signature types.
|
||||
enum SignatureType {
|
||||
Illegal, // Default value
|
||||
Invalid,
|
||||
Caller,
|
||||
Ecrecover,
|
||||
EIP712,
|
||||
Trezor,
|
||||
Contract,
|
||||
PreSigned
|
||||
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.
|
||||
@@ -43,7 +44,8 @@ contract MSignatureValidator is
|
||||
function isValidSignature(
|
||||
bytes32 hash,
|
||||
address signer,
|
||||
bytes memory signature)
|
||||
bytes memory signature
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (bool isValid);
|
||||
|
@@ -25,6 +25,30 @@ 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.
|
||||
|
@@ -20,13 +20,18 @@ pragma solidity ^0.4.24;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../protocol/Exchange/MixinSignatureValidator.sol";
|
||||
import "../../protocol/Exchange/MixinTransactions.sol";
|
||||
|
||||
contract TestSignatureValidator is MixinSignatureValidator {
|
||||
contract TestSignatureValidator is
|
||||
MixinSignatureValidator,
|
||||
MixinTransactions
|
||||
{
|
||||
|
||||
function publicIsValidSignature(
|
||||
bytes32 hash,
|
||||
address signer,
|
||||
bytes memory signature)
|
||||
bytes memory signature
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (bool isValid)
|
||||
|
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@@ -21,15 +21,68 @@ pragma solidity ^0.4.24;
|
||||
contract LibBytes {
|
||||
|
||||
// Revert reasons
|
||||
string constant GT_ZERO_LENGTH_REQUIRED = "Length must be greater than 0.";
|
||||
string constant GTE_4_LENGTH_REQUIRED = "Length must be greater than or equal to 4.";
|
||||
string constant GTE_20_LENGTH_REQUIRED = "Length must be greater than or equal to 20.";
|
||||
string constant GTE_32_LENGTH_REQUIRED = "Length must be greater than or equal to 32.";
|
||||
string constant INDEX_OUT_OF_BOUNDS = "Specified array index is out of bounds.";
|
||||
|
||||
/// @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 popByte(bytes memory b)
|
||||
internal
|
||||
pure
|
||||
returns (bytes1 result)
|
||||
{
|
||||
require(
|
||||
b.length > 0,
|
||||
GT_ZERO_LENGTH_REQUIRED
|
||||
);
|
||||
|
||||
// Store last byte.
|
||||
result = b[b.length - 1];
|
||||
|
||||
assembly {
|
||||
// Decrement length of byte array.
|
||||
let newLen := sub(mload(b), 1)
|
||||
mstore(b, newLen)
|
||||
}
|
||||
return 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 popAddress(bytes memory b)
|
||||
internal
|
||||
pure
|
||||
returns (address result)
|
||||
{
|
||||
require(
|
||||
b.length >= 20,
|
||||
GTE_20_LENGTH_REQUIRED
|
||||
);
|
||||
|
||||
// Store last 20 bytes.
|
||||
result = readAddress(b, b.length - 20);
|
||||
|
||||
assembly {
|
||||
// Subtract 20 from byte array length.
|
||||
let newLen := sub(mload(b), 20)
|
||||
mstore(b, newLen)
|
||||
}
|
||||
return 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 areBytesEqual(bytes memory lhs, bytes memory rhs)
|
||||
function areBytesEqual(
|
||||
bytes memory lhs,
|
||||
bytes memory rhs
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (bool equal)
|
||||
@@ -63,7 +116,8 @@ contract LibBytes {
|
||||
/// @return address from byte array.
|
||||
function readAddress(
|
||||
bytes memory b,
|
||||
uint256 index)
|
||||
uint256 index
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (address result)
|
||||
@@ -95,7 +149,8 @@ contract LibBytes {
|
||||
function writeAddress(
|
||||
bytes memory b,
|
||||
uint256 index,
|
||||
address input)
|
||||
address input
|
||||
)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
@@ -132,7 +187,8 @@ contract LibBytes {
|
||||
/// @return bytes32 value from byte array.
|
||||
function readBytes32(
|
||||
bytes memory b,
|
||||
uint256 index)
|
||||
uint256 index
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (bytes32 result)
|
||||
@@ -159,7 +215,8 @@ contract LibBytes {
|
||||
function writeBytes32(
|
||||
bytes memory b,
|
||||
uint256 index,
|
||||
bytes32 input)
|
||||
bytes32 input
|
||||
)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
@@ -183,7 +240,8 @@ contract LibBytes {
|
||||
/// @return uint256 value from byte array.
|
||||
function readUint256(
|
||||
bytes memory b,
|
||||
uint256 index)
|
||||
uint256 index
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (uint256 result)
|
||||
@@ -198,7 +256,8 @@ contract LibBytes {
|
||||
function writeUint256(
|
||||
bytes memory b,
|
||||
uint256 index,
|
||||
uint256 input)
|
||||
uint256 input
|
||||
)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
|
@@ -1,6 +1,4 @@
|
||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
|
||||
import { crypto } from './crypto';
|
||||
import { crypto, generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
|
||||
export const addressUtils = {
|
||||
generatePseudoRandomAddress(): string {
|
||||
|
@@ -15,6 +15,7 @@ import * as TestLibs from '../artifacts/TestLibs.json';
|
||||
import * as TestSignatureValidator from '../artifacts/TestSignatureValidator.json';
|
||||
import * as TokenRegistry from '../artifacts/TokenRegistry.json';
|
||||
import * as EtherToken from '../artifacts/WETH9.json';
|
||||
import * as Whitelist from '../artifacts/Whitelist.json';
|
||||
import * as ZRX from '../artifacts/ZRXToken.json';
|
||||
|
||||
export const artifacts = {
|
||||
@@ -33,5 +34,6 @@ export const artifacts = {
|
||||
TestLibs: (TestLibs as any) as ContractArtifact,
|
||||
TestSignatureValidator: (TestSignatureValidator as any) as ContractArtifact,
|
||||
TokenRegistry: (TokenRegistry as any) as ContractArtifact,
|
||||
Whitelist: (Whitelist as any) as ContractArtifact,
|
||||
ZRX: (ZRX as any) as ContractArtifact,
|
||||
};
|
||||
|
@@ -28,6 +28,7 @@ export const constants = {
|
||||
DUMMY_TOKEN_SYMBOL: '',
|
||||
DUMMY_TOKEN_DECIMALS: new BigNumber(18),
|
||||
DUMMY_TOKEN_TOTAL_SUPPLY: new BigNumber(0),
|
||||
NULL_BYTES: '0x',
|
||||
NUM_DUMMY_ERC20_TO_DEPLOY: 3,
|
||||
NUM_DUMMY_ERC721_TO_DEPLOY: 1,
|
||||
NUM_ERC721_TOKENS_TO_MINT: 2,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Provider } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { DummyERC20TokenContract } from '../contract_wrappers/generated/dummy_e_r_c20_token';
|
||||
@@ -16,18 +16,19 @@ export class ERC20Wrapper {
|
||||
private _contractOwnerAddress: string;
|
||||
private _web3Wrapper: Web3Wrapper;
|
||||
private _provider: Provider;
|
||||
private _dummyTokenContracts?: DummyERC20TokenContract[];
|
||||
private _dummyTokenContracts: DummyERC20TokenContract[];
|
||||
private _proxyContract?: ERC20ProxyContract;
|
||||
constructor(provider: Provider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
|
||||
this._dummyTokenContracts = [];
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._provider = provider;
|
||||
this._tokenOwnerAddresses = tokenOwnerAddresses;
|
||||
this._contractOwnerAddress = contractOwnerAddress;
|
||||
}
|
||||
public async deployDummyTokensAsync(): Promise<DummyERC20TokenContract[]> {
|
||||
this._dummyTokenContracts = await Promise.all(
|
||||
_.times(constants.NUM_DUMMY_ERC20_TO_DEPLOY, async () =>
|
||||
DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
for (let i = 0; i < constants.NUM_DUMMY_ERC20_TO_DEPLOY; i++) {
|
||||
this._dummyTokenContracts.push(
|
||||
await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
artifacts.DummyERC20Token,
|
||||
this._provider,
|
||||
txDefaults,
|
||||
@@ -36,8 +37,8 @@ export class ERC20Wrapper {
|
||||
constants.DUMMY_TOKEN_DECIMALS,
|
||||
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
}
|
||||
return this._dummyTokenContracts;
|
||||
}
|
||||
public async deployProxyAsync(): Promise<ERC20ProxyContract> {
|
||||
@@ -51,44 +52,41 @@ export class ERC20Wrapper {
|
||||
public async setBalancesAndAllowancesAsync(): Promise<void> {
|
||||
this._validateDummyTokenContractsExistOrThrow();
|
||||
this._validateProxyContractExistsOrThrow();
|
||||
const setBalancePromises: Array<Promise<string>> = [];
|
||||
const setAllowancePromises: Array<Promise<string>> = [];
|
||||
_.forEach(this._dummyTokenContracts, dummyTokenContract => {
|
||||
_.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
|
||||
setBalancePromises.push(
|
||||
dummyTokenContract.setBalance.sendTransactionAsync(
|
||||
for (const dummyTokenContract of this._dummyTokenContracts) {
|
||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await dummyTokenContract.setBalance.sendTransactionAsync(
|
||||
tokenOwnerAddress,
|
||||
constants.INITIAL_ERC20_BALANCE,
|
||||
{ from: this._contractOwnerAddress },
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
setAllowancePromises.push(
|
||||
dummyTokenContract.approve.sendTransactionAsync(
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await dummyTokenContract.approve.sendTransactionAsync(
|
||||
(this._proxyContract as ERC20ProxyContract).address,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
{ from: tokenOwnerAddress },
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
});
|
||||
});
|
||||
const txHashes = await Promise.all([...setBalancePromises, ...setAllowancePromises]);
|
||||
await Promise.all(_.map(txHashes, async txHash => this._web3Wrapper.awaitTransactionSuccessAsync(txHash)));
|
||||
}
|
||||
}
|
||||
}
|
||||
public async getBalancesAsync(): Promise<ERC20BalancesByOwner> {
|
||||
this._validateDummyTokenContractsExistOrThrow();
|
||||
const balancesByOwner: ERC20BalancesByOwner = {};
|
||||
const balancePromises: Array<Promise<BigNumber>> = [];
|
||||
const balances: BigNumber[] = [];
|
||||
const balanceInfo: Array<{ tokenOwnerAddress: string; tokenAddress: string }> = [];
|
||||
_.forEach(this._dummyTokenContracts, dummyTokenContract => {
|
||||
_.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
|
||||
balancePromises.push(dummyTokenContract.balanceOf.callAsync(tokenOwnerAddress));
|
||||
for (const dummyTokenContract of this._dummyTokenContracts) {
|
||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||
balances.push(await dummyTokenContract.balanceOf.callAsync(tokenOwnerAddress));
|
||||
balanceInfo.push({
|
||||
tokenOwnerAddress,
|
||||
tokenAddress: dummyTokenContract.address,
|
||||
});
|
||||
});
|
||||
});
|
||||
const balances = await Promise.all(balancePromises);
|
||||
}
|
||||
}
|
||||
_.forEach(balances, (balance, balanceIndex) => {
|
||||
const tokenAddress = balanceInfo[balanceIndex].tokenAddress;
|
||||
const tokenOwnerAddress = balanceInfo[balanceIndex].tokenOwnerAddress;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { Provider } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { DummyERC721TokenContract } from '../contract_wrappers/generated/dummy_e_r_c721_token';
|
||||
@@ -17,27 +17,28 @@ export class ERC721Wrapper {
|
||||
private _contractOwnerAddress: string;
|
||||
private _web3Wrapper: Web3Wrapper;
|
||||
private _provider: Provider;
|
||||
private _dummyTokenContracts?: DummyERC721TokenContract[];
|
||||
private _dummyTokenContracts: DummyERC721TokenContract[];
|
||||
private _proxyContract?: ERC721ProxyContract;
|
||||
private _initialTokenIdsByOwner: ERC721TokenIdsByOwner = {};
|
||||
constructor(provider: Provider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._provider = provider;
|
||||
this._dummyTokenContracts = [];
|
||||
this._tokenOwnerAddresses = tokenOwnerAddresses;
|
||||
this._contractOwnerAddress = contractOwnerAddress;
|
||||
}
|
||||
public async deployDummyTokensAsync(): Promise<DummyERC721TokenContract[]> {
|
||||
this._dummyTokenContracts = await Promise.all(
|
||||
_.times(constants.NUM_DUMMY_ERC721_TO_DEPLOY, async () =>
|
||||
DummyERC721TokenContract.deployFrom0xArtifactAsync(
|
||||
for (let i = 0; i < constants.NUM_DUMMY_ERC721_TO_DEPLOY; i++) {
|
||||
this._dummyTokenContracts.push(
|
||||
await DummyERC721TokenContract.deployFrom0xArtifactAsync(
|
||||
artifacts.DummyERC721Token,
|
||||
this._provider,
|
||||
txDefaults,
|
||||
constants.DUMMY_TOKEN_NAME,
|
||||
constants.DUMMY_TOKEN_SYMBOL,
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
}
|
||||
return this._dummyTokenContracts;
|
||||
}
|
||||
public async deployProxyAsync(): Promise<ERC721ProxyContract> {
|
||||
@@ -51,17 +52,16 @@ export class ERC721Wrapper {
|
||||
public async setBalancesAndAllowancesAsync(): Promise<void> {
|
||||
this._validateDummyTokenContractsExistOrThrow();
|
||||
this._validateProxyContractExistsOrThrow();
|
||||
const setBalancePromises: Array<Promise<string>> = [];
|
||||
const setAllowancePromises: Array<Promise<string>> = [];
|
||||
this._initialTokenIdsByOwner = {};
|
||||
_.forEach(this._dummyTokenContracts, dummyTokenContract => {
|
||||
_.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
|
||||
_.forEach(_.range(constants.NUM_ERC721_TOKENS_TO_MINT), () => {
|
||||
for (const dummyTokenContract of this._dummyTokenContracts) {
|
||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||
for (let i = 0; i < constants.NUM_ERC721_TOKENS_TO_MINT; i++) {
|
||||
const tokenId = generatePseudoRandomSalt();
|
||||
setBalancePromises.push(
|
||||
dummyTokenContract.mint.sendTransactionAsync(tokenOwnerAddress, tokenId, {
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await dummyTokenContract.mint.sendTransactionAsync(tokenOwnerAddress, tokenId, {
|
||||
from: this._contractOwnerAddress,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress])) {
|
||||
this._initialTokenIdsByOwner[tokenOwnerAddress] = {
|
||||
@@ -72,41 +72,39 @@ export class ERC721Wrapper {
|
||||
this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address] = [];
|
||||
}
|
||||
this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address].push(tokenId);
|
||||
});
|
||||
}
|
||||
const shouldApprove = true;
|
||||
setAllowancePromises.push(
|
||||
dummyTokenContract.setApprovalForAll.sendTransactionAsync(
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await dummyTokenContract.setApprovalForAll.sendTransactionAsync(
|
||||
(this._proxyContract as ERC721ProxyContract).address,
|
||||
shouldApprove,
|
||||
{ from: tokenOwnerAddress },
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
});
|
||||
});
|
||||
const txHashes = await Promise.all([...setBalancePromises, ...setAllowancePromises]);
|
||||
await Promise.all(_.map(txHashes, async txHash => this._web3Wrapper.awaitTransactionSuccessAsync(txHash)));
|
||||
}
|
||||
}
|
||||
}
|
||||
public async getBalancesAsync(): Promise<ERC721TokenIdsByOwner> {
|
||||
this._validateDummyTokenContractsExistOrThrow();
|
||||
this._validateBalancesAndAllowancesSetOrThrow();
|
||||
const tokenIdsByOwner: ERC721TokenIdsByOwner = {};
|
||||
const tokenOwnerPromises: Array<Promise<string>> = [];
|
||||
const tokenOwnerAddresses: string[] = [];
|
||||
const tokenInfo: Array<{ tokenId: BigNumber; tokenAddress: string }> = [];
|
||||
_.forEach(this._dummyTokenContracts, dummyTokenContract => {
|
||||
_.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
|
||||
for (const dummyTokenContract of this._dummyTokenContracts) {
|
||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||
const initialTokenOwnerIds = this._initialTokenIdsByOwner[tokenOwnerAddress][
|
||||
dummyTokenContract.address
|
||||
];
|
||||
_.forEach(initialTokenOwnerIds, tokenId => {
|
||||
tokenOwnerPromises.push(dummyTokenContract.ownerOf.callAsync(tokenId));
|
||||
for (const tokenId of initialTokenOwnerIds) {
|
||||
tokenOwnerAddresses.push(await dummyTokenContract.ownerOf.callAsync(tokenId));
|
||||
tokenInfo.push({
|
||||
tokenId,
|
||||
tokenAddress: dummyTokenContract.address,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
const tokenOwnerAddresses = await Promise.all(tokenOwnerPromises);
|
||||
}
|
||||
}
|
||||
}
|
||||
_.forEach(tokenOwnerAddresses, (tokenOwnerAddress, ownerIndex) => {
|
||||
const tokenAddress = tokenInfo[ownerIndex].tokenAddress;
|
||||
const tokenId = tokenInfo[ownerIndex].tokenId;
|
||||
|
@@ -1,22 +1,25 @@
|
||||
import { Provider, SignedOrder, TransactionReceiptWithDecodedLogs } from '@0xproject/types';
|
||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { LogEntry, Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { ExchangeContract } from '../contract_wrappers/generated/exchange';
|
||||
|
||||
import { constants } from './constants';
|
||||
import { formatters } from './formatters';
|
||||
import { logDecoder } from './log_decoder';
|
||||
import { LogDecoder } from './log_decoder';
|
||||
import { orderUtils } from './order_utils';
|
||||
import { AssetProxyId, OrderInfo, SignedTransaction } from './types';
|
||||
import { OrderInfo, SignedTransaction } from './types';
|
||||
|
||||
export class ExchangeWrapper {
|
||||
private _exchange: ExchangeContract;
|
||||
private _web3Wrapper: Web3Wrapper;
|
||||
private _logDecoder: LogDecoder;
|
||||
constructor(exchangeContract: ExchangeContract, provider: Provider) {
|
||||
this._exchange = exchangeContract;
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._logDecoder = new LogDecoder(this._web3Wrapper, this._exchange.address);
|
||||
}
|
||||
public async fillOrderAsync(
|
||||
signedOrder: SignedOrder,
|
||||
@@ -30,13 +33,13 @@ export class ExchangeWrapper {
|
||||
params.signature,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async cancelOrderAsync(signedOrder: SignedOrder, from: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = orderUtils.createCancel(signedOrder);
|
||||
const txHash = await this._exchange.cancelOrder.sendTransactionAsync(params.order, { from });
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async fillOrKillOrderAsync(
|
||||
@@ -51,7 +54,7 @@ export class ExchangeWrapper {
|
||||
params.signature,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async fillOrderNoThrowAsync(
|
||||
@@ -66,7 +69,7 @@ export class ExchangeWrapper {
|
||||
params.signature,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async batchFillOrdersAsync(
|
||||
@@ -81,7 +84,7 @@ export class ExchangeWrapper {
|
||||
params.signatures,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async batchFillOrKillOrdersAsync(
|
||||
@@ -96,7 +99,7 @@ export class ExchangeWrapper {
|
||||
params.signatures,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async batchFillOrdersNoThrowAsync(
|
||||
@@ -111,7 +114,7 @@ export class ExchangeWrapper {
|
||||
params.signatures,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async marketSellOrdersAsync(
|
||||
@@ -126,7 +129,7 @@ export class ExchangeWrapper {
|
||||
params.signatures,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async marketSellOrdersNoThrowAsync(
|
||||
@@ -141,7 +144,7 @@ export class ExchangeWrapper {
|
||||
params.signatures,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async marketBuyOrdersAsync(
|
||||
@@ -156,7 +159,7 @@ export class ExchangeWrapper {
|
||||
params.signatures,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async marketBuyOrdersNoThrowAsync(
|
||||
@@ -171,7 +174,7 @@ export class ExchangeWrapper {
|
||||
params.signatures,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async batchCancelOrdersAsync(
|
||||
@@ -180,12 +183,12 @@ export class ExchangeWrapper {
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = formatters.createBatchCancel(orders);
|
||||
const txHash = await this._exchange.batchCancelOrders.sendTransactionAsync(params.orders, { from });
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async cancelOrdersUpToAsync(salt: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const txHash = await this._exchange.cancelOrdersUpTo.sendTransactionAsync(salt, { from });
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async registerAssetProxyAsync(
|
||||
@@ -203,7 +206,7 @@ export class ExchangeWrapper {
|
||||
oldAssetProxyAddress,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async executeTransactionAsync(
|
||||
@@ -217,7 +220,7 @@ export class ExchangeWrapper {
|
||||
signedTx.signature,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async getTakerAssetFilledAmountAsync(orderHashHex: string): Promise<BigNumber> {
|
||||
@@ -241,13 +244,7 @@ export class ExchangeWrapper {
|
||||
params.rightSignature,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
private async _getTxWithDecodedExchangeLogsAsync(txHash: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const tx = await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address);
|
||||
tx.logs = _.map(tx.logs, log => logDecoder.decodeLogOrThrow(log));
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
}
|
||||
|
@@ -13,8 +13,8 @@ export const formatters = {
|
||||
takerAssetFillAmounts,
|
||||
};
|
||||
_.forEach(signedOrders, signedOrder => {
|
||||
const orderStruct = orderUtils.getOrderStruct(signedOrder);
|
||||
batchFill.orders.push(orderStruct);
|
||||
const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
batchFill.orders.push(orderWithoutExchangeAddress);
|
||||
batchFill.signatures.push(signedOrder.signature);
|
||||
if (takerAssetFillAmounts.length < signedOrders.length) {
|
||||
batchFill.takerAssetFillAmounts.push(signedOrder.takerAssetAmount);
|
||||
@@ -29,8 +29,8 @@ export const formatters = {
|
||||
takerAssetFillAmount,
|
||||
};
|
||||
_.forEach(signedOrders, signedOrder => {
|
||||
const orderStruct = orderUtils.getOrderStruct(signedOrder);
|
||||
marketSellOrders.orders.push(orderStruct);
|
||||
const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
marketSellOrders.orders.push(orderWithoutExchangeAddress);
|
||||
marketSellOrders.signatures.push(signedOrder.signature);
|
||||
});
|
||||
return marketSellOrders;
|
||||
@@ -42,8 +42,8 @@ export const formatters = {
|
||||
makerAssetFillAmount,
|
||||
};
|
||||
_.forEach(signedOrders, signedOrder => {
|
||||
const orderStruct = orderUtils.getOrderStruct(signedOrder);
|
||||
marketBuyOrders.orders.push(orderStruct);
|
||||
const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
marketBuyOrders.orders.push(orderWithoutExchangeAddress);
|
||||
marketBuyOrders.signatures.push(signedOrder.signature);
|
||||
});
|
||||
return marketBuyOrders;
|
||||
@@ -53,8 +53,8 @@ export const formatters = {
|
||||
orders: [],
|
||||
};
|
||||
_.forEach(signedOrders, signedOrder => {
|
||||
const orderStruct = orderUtils.getOrderStruct(signedOrder);
|
||||
batchCancel.orders.push(orderStruct);
|
||||
const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
batchCancel.orders.push(orderWithoutExchangeAddress);
|
||||
});
|
||||
return batchCancel;
|
||||
},
|
||||
|
@@ -1,19 +1,24 @@
|
||||
import { ContractArtifact } from '@0xproject/sol-compiler';
|
||||
import { AbiDefinition, LogEntry, LogWithDecodedArgs, RawLog } from '@0xproject/types';
|
||||
import { AbiDecoder, BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import {
|
||||
AbiDefinition,
|
||||
DecodedLogArgs,
|
||||
LogEntry,
|
||||
LogWithDecodedArgs,
|
||||
RawLog,
|
||||
TransactionReceiptWithDecodedLogs,
|
||||
} from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { constants } from './constants';
|
||||
|
||||
const abiArrays: AbiDefinition[][] = [];
|
||||
_.forEach(artifacts, (artifact: ContractArtifact) => {
|
||||
const compilerOutput = artifact.compilerOutput;
|
||||
abiArrays.push(compilerOutput.abi);
|
||||
});
|
||||
const abiDecoder = new AbiDecoder(abiArrays);
|
||||
|
||||
export const logDecoder = {
|
||||
wrapLogBigNumbers(log: any): any {
|
||||
export class LogDecoder {
|
||||
private _web3Wrapper: Web3Wrapper;
|
||||
private _contractAddress: string;
|
||||
private _abiDecoder: AbiDecoder;
|
||||
public static wrapLogBigNumbers(log: any): any {
|
||||
const argNames = _.keys(log.args);
|
||||
for (const argName of argNames) {
|
||||
const isWeb3BigNumber = _.startsWith(log.args[argName].constructor.toString(), 'function BigNumber(');
|
||||
@@ -21,13 +26,29 @@ export const logDecoder = {
|
||||
log.args[argName] = new BigNumber(log.args[argName]);
|
||||
}
|
||||
}
|
||||
},
|
||||
decodeLogOrThrow<ArgsType>(log: LogEntry): LogWithDecodedArgs<ArgsType> | RawLog {
|
||||
const logWithDecodedArgsOrLog = abiDecoder.tryToDecodeLogOrNoop(log);
|
||||
}
|
||||
constructor(web3Wrapper: Web3Wrapper, contractAddress: string) {
|
||||
this._web3Wrapper = web3Wrapper;
|
||||
this._contractAddress = contractAddress;
|
||||
const abiArrays: AbiDefinition[][] = [];
|
||||
_.forEach(artifacts, (artifact: ContractArtifact) => {
|
||||
const compilerOutput = artifact.compilerOutput;
|
||||
abiArrays.push(compilerOutput.abi);
|
||||
});
|
||||
this._abiDecoder = new AbiDecoder(abiArrays);
|
||||
}
|
||||
public decodeLogOrThrow<ArgsType extends DecodedLogArgs>(log: LogEntry): LogWithDecodedArgs<ArgsType> | RawLog {
|
||||
const logWithDecodedArgsOrLog = this._abiDecoder.tryToDecodeLogOrNoop(log);
|
||||
if (_.isUndefined((logWithDecodedArgsOrLog as LogWithDecodedArgs<ArgsType>).args)) {
|
||||
throw new Error(`Unable to decode log: ${JSON.stringify(log)}`);
|
||||
}
|
||||
logDecoder.wrapLogBigNumbers(logWithDecodedArgsOrLog);
|
||||
LogDecoder.wrapLogBigNumbers(logWithDecodedArgsOrLog);
|
||||
return logWithDecodedArgsOrLog;
|
||||
},
|
||||
};
|
||||
}
|
||||
public async getTxWithDecodedLogsAsync(txHash: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const tx = await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
tx.logs = _.filter(tx.logs, log => log.address === this._contractAddress);
|
||||
tx.logs = _.map(tx.logs, log => this.decodeLogOrThrow(log));
|
||||
return tx;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { LogWithDecodedArgs, SignedOrder } from '@0xproject/types';
|
||||
import { assetProxyUtils, crypto, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import ethUtil = require('ethereumjs-util');
|
||||
import * as _ from 'lodash';
|
||||
|
||||
@@ -14,17 +16,13 @@ import {
|
||||
ExchangeContract,
|
||||
FillContractEventArgs,
|
||||
} from '../contract_wrappers/generated/exchange';
|
||||
import { assetProxyUtils } from '../utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../utils/chai_setup';
|
||||
import { constants } from '../utils/constants';
|
||||
import { crypto } from '../utils/crypto';
|
||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../utils/order_factory';
|
||||
import { orderUtils } from '../utils/order_utils';
|
||||
import {
|
||||
AssetProxyId,
|
||||
ContractName,
|
||||
ERC20BalancesByOwner,
|
||||
ERC721TokenIdsByOwner,
|
||||
@@ -122,7 +120,7 @@ export class MatchOrderTester {
|
||||
const feeRecipientAddressRight = signedOrderRight.feeRecipientAddress;
|
||||
// Verify Left order preconditions
|
||||
const orderTakerAssetFilledAmountLeft = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrderLeft),
|
||||
orderHashUtils.getOrderHashHex(signedOrderLeft),
|
||||
);
|
||||
const expectedOrderFilledAmountLeft = initialTakerAssetFilledAmountLeft
|
||||
? initialTakerAssetFilledAmountLeft
|
||||
@@ -130,7 +128,7 @@ export class MatchOrderTester {
|
||||
expect(expectedOrderFilledAmountLeft).to.be.bignumber.equal(orderTakerAssetFilledAmountLeft);
|
||||
// Verify Right order preconditions
|
||||
const orderTakerAssetFilledAmountRight = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrderRight),
|
||||
orderHashUtils.getOrderHashHex(signedOrderRight),
|
||||
);
|
||||
const expectedOrderFilledAmountRight = initialTakerAssetFilledAmountRight
|
||||
? initialTakerAssetFilledAmountRight
|
||||
@@ -181,7 +179,7 @@ export class MatchOrderTester {
|
||||
orderTakerAssetFilledAmountRight: BigNumber,
|
||||
): Promise<TransferAmounts> {
|
||||
let amountBoughtByLeftMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrderLeft),
|
||||
orderHashUtils.getOrderHashHex(signedOrderLeft),
|
||||
);
|
||||
amountBoughtByLeftMaker = amountBoughtByLeftMaker.minus(orderTakerAssetFilledAmountLeft);
|
||||
const amountSoldByLeftMaker = amountBoughtByLeftMaker
|
||||
@@ -192,7 +190,7 @@ export class MatchOrderTester {
|
||||
.dividedToIntegerBy(signedOrderRight.makerAssetAmount);
|
||||
const amountReceivedByTaker = amountSoldByLeftMaker.minus(amountReceivedByRightMaker);
|
||||
let amountBoughtByRightMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrderRight),
|
||||
orderHashUtils.getOrderHashHex(signedOrderRight),
|
||||
);
|
||||
amountBoughtByRightMaker = amountBoughtByRightMaker.minus(orderTakerAssetFilledAmountRight);
|
||||
const amountSoldByRightMaker = amountBoughtByRightMaker
|
||||
|
@@ -1,20 +1,22 @@
|
||||
import { Provider, TransactionReceiptWithDecodedLogs } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AssetProxyOwnerContract } from '../contract_wrappers/generated/asset_proxy_owner';
|
||||
import { MultiSigWalletContract } from '../contract_wrappers/generated/multi_sig_wallet';
|
||||
|
||||
import { constants } from './constants';
|
||||
import { logDecoder } from './log_decoder';
|
||||
import { LogDecoder } from './log_decoder';
|
||||
|
||||
export class MultiSigWrapper {
|
||||
private _multiSig: MultiSigWalletContract;
|
||||
private _web3Wrapper: Web3Wrapper;
|
||||
private _logDecoder: LogDecoder;
|
||||
constructor(multiSigContract: MultiSigWalletContract, provider: Provider) {
|
||||
this._multiSig = multiSigContract;
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._logDecoder = new LogDecoder(this._web3Wrapper, this._multiSig.address);
|
||||
}
|
||||
public async submitTransactionAsync(
|
||||
destination: string,
|
||||
@@ -26,17 +28,17 @@ export class MultiSigWrapper {
|
||||
const txHash = await this._multiSig.submitTransaction.sendTransactionAsync(destination, value, data, {
|
||||
from,
|
||||
});
|
||||
const tx = await this._getTxWithDecodedMultiSigLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async confirmTransactionAsync(txId: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const txHash = await this._multiSig.confirmTransaction.sendTransactionAsync(txId, { from });
|
||||
const tx = await this._getTxWithDecodedMultiSigLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async executeTransactionAsync(txId: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const txHash = await this._multiSig.executeTransaction.sendTransactionAsync(txId, { from });
|
||||
const tx = await this._getTxWithDecodedMultiSigLogsAsync(txHash);
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async executeRemoveAuthorizedAddressAsync(
|
||||
@@ -45,13 +47,7 @@ export class MultiSigWrapper {
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const txHash = await (this
|
||||
._multiSig as AssetProxyOwnerContract).executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from });
|
||||
const tx = await this._getTxWithDecodedMultiSigLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
private async _getTxWithDecodedMultiSigLogsAsync(txHash: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const tx = await this._web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
tx.logs = _.filter(tx.logs, log => log.address === this._multiSig.address);
|
||||
tx.logs = _.map(tx.logs, log => logDecoder.decodeLogOrThrow(log));
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
}
|
||||
|
@@ -1,25 +1,24 @@
|
||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { SignedOrder, UnsignedOrder } from '@0xproject/types';
|
||||
import { generatePseudoRandomSalt, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { Order, SignatureType, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { constants } from './constants';
|
||||
import { orderUtils } from './order_utils';
|
||||
import { signingUtils } from './signing_utils';
|
||||
import { SignatureType } from './types';
|
||||
|
||||
export class OrderFactory {
|
||||
private _defaultOrderParams: Partial<UnsignedOrder>;
|
||||
private _defaultOrderParams: Partial<Order>;
|
||||
private _privateKey: Buffer;
|
||||
constructor(privateKey: Buffer, defaultOrderParams: Partial<UnsignedOrder>) {
|
||||
constructor(privateKey: Buffer, defaultOrderParams: Partial<Order>) {
|
||||
this._defaultOrderParams = defaultOrderParams;
|
||||
this._privateKey = privateKey;
|
||||
}
|
||||
public newSignedOrder(
|
||||
customOrderParams: Partial<UnsignedOrder> = {},
|
||||
signatureType: SignatureType = SignatureType.Ecrecover,
|
||||
customOrderParams: Partial<Order> = {},
|
||||
signatureType: SignatureType = SignatureType.EthSign,
|
||||
): SignedOrder {
|
||||
const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000));
|
||||
const tenMinutes = 10 * 60 * 1000;
|
||||
const randomExpiration = new BigNumber(Date.now() + tenMinutes);
|
||||
const order = ({
|
||||
senderAddress: constants.NULL_ADDRESS,
|
||||
expirationTimeSeconds: randomExpiration,
|
||||
@@ -27,8 +26,8 @@ export class OrderFactory {
|
||||
takerAddress: constants.NULL_ADDRESS,
|
||||
...this._defaultOrderParams,
|
||||
...customOrderParams,
|
||||
} as any) as UnsignedOrder;
|
||||
const orderHashBuff = orderUtils.getOrderHashBuff(order);
|
||||
} as any) as Order;
|
||||
const orderHashBuff = orderHashUtils.getOrderHashBuff(order);
|
||||
const signature = signingUtils.signMessage(orderHashBuff, this._privateKey, signatureType);
|
||||
const signedOrder = {
|
||||
...order,
|
||||
|
@@ -1,14 +1,13 @@
|
||||
import { Order, SignedOrder, UnsignedOrder } from '@0xproject/types';
|
||||
import { Order, OrderWithoutExchangeAddress, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import ethUtil = require('ethereumjs-util');
|
||||
|
||||
import { crypto } from './crypto';
|
||||
import { CancelOrder, MatchOrder } from './types';
|
||||
|
||||
export const orderUtils = {
|
||||
createFill: (signedOrder: SignedOrder, takerAssetFillAmount?: BigNumber) => {
|
||||
const fill = {
|
||||
order: orderUtils.getOrderStruct(signedOrder),
|
||||
order: orderUtils.getOrderWithoutExchangeAddress(signedOrder),
|
||||
takerAssetFillAmount: takerAssetFillAmount || signedOrder.takerAssetAmount,
|
||||
signature: signedOrder.signature,
|
||||
};
|
||||
@@ -16,12 +15,12 @@ export const orderUtils = {
|
||||
},
|
||||
createCancel(signedOrder: SignedOrder, takerAssetCancelAmount?: BigNumber): CancelOrder {
|
||||
const cancel = {
|
||||
order: orderUtils.getOrderStruct(signedOrder),
|
||||
order: orderUtils.getOrderWithoutExchangeAddress(signedOrder),
|
||||
takerAssetCancelAmount: takerAssetCancelAmount || signedOrder.takerAssetAmount,
|
||||
};
|
||||
return cancel;
|
||||
},
|
||||
getOrderStruct(signedOrder: SignedOrder): Order {
|
||||
getOrderWithoutExchangeAddress(signedOrder: SignedOrder): OrderWithoutExchangeAddress {
|
||||
const orderStruct = {
|
||||
senderAddress: signedOrder.senderAddress,
|
||||
makerAddress: signedOrder.makerAddress,
|
||||
@@ -38,75 +37,10 @@ export const orderUtils = {
|
||||
};
|
||||
return orderStruct;
|
||||
},
|
||||
getDomainSeparatorSchemaHex(): string {
|
||||
const domainSeparatorSchemaHashBuff = crypto.solSHA3(['DomainSeparator(address contract)']);
|
||||
const schemaHashHex = `0x${domainSeparatorSchemaHashBuff.toString('hex')}`;
|
||||
return schemaHashHex;
|
||||
},
|
||||
getDomainSeparatorHashHex(exchangeAddress: string): string {
|
||||
const domainSeparatorHashBuff = crypto.solSHA3([exchangeAddress]);
|
||||
const domainSeparatorHashHex = `0x${domainSeparatorHashBuff.toString('hex')}`;
|
||||
return domainSeparatorHashHex;
|
||||
},
|
||||
getOrderSchemaHex(): string {
|
||||
const orderSchemaHashBuff = crypto.solSHA3([
|
||||
'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,',
|
||||
')',
|
||||
]);
|
||||
const schemaHashHex = `0x${orderSchemaHashBuff.toString('hex')}`;
|
||||
return schemaHashHex;
|
||||
},
|
||||
getOrderHashBuff(order: SignedOrder | UnsignedOrder): Buffer {
|
||||
const makerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.makerAssetData)]);
|
||||
const takerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.takerAssetData)]);
|
||||
|
||||
const orderParamsHashBuff = crypto.solSHA3([
|
||||
order.makerAddress,
|
||||
order.takerAddress,
|
||||
order.feeRecipientAddress,
|
||||
order.senderAddress,
|
||||
order.makerAssetAmount,
|
||||
order.takerAssetAmount,
|
||||
order.makerFee,
|
||||
order.takerFee,
|
||||
order.expirationTimeSeconds,
|
||||
order.salt,
|
||||
makerAssetDataHash,
|
||||
takerAssetDataHash,
|
||||
]);
|
||||
const orderParamsHashHex = `0x${orderParamsHashBuff.toString('hex')}`;
|
||||
const orderSchemaHashHex = orderUtils.getOrderSchemaHex();
|
||||
const domainSeparatorHashHex = this.getDomainSeparatorHashHex(order.exchangeAddress);
|
||||
const domainSeparatorSchemaHex = this.getDomainSeparatorSchemaHex();
|
||||
const orderHashBuff = crypto.solSHA3([
|
||||
new BigNumber(domainSeparatorSchemaHex),
|
||||
new BigNumber(domainSeparatorHashHex),
|
||||
new BigNumber(orderSchemaHashHex),
|
||||
new BigNumber(orderParamsHashHex),
|
||||
]);
|
||||
return orderHashBuff;
|
||||
},
|
||||
getOrderHashHex(order: SignedOrder | UnsignedOrder): string {
|
||||
const orderHashBuff = orderUtils.getOrderHashBuff(order);
|
||||
const orderHashHex = `0x${orderHashBuff.toString('hex')}`;
|
||||
return orderHashHex;
|
||||
},
|
||||
createMatchOrders(signedOrderLeft: SignedOrder, signedOrderRight: SignedOrder): MatchOrder {
|
||||
const fill = {
|
||||
left: orderUtils.getOrderStruct(signedOrderLeft),
|
||||
right: orderUtils.getOrderStruct(signedOrderRight),
|
||||
left: orderUtils.getOrderWithoutExchangeAddress(signedOrderLeft),
|
||||
right: orderUtils.getOrderWithoutExchangeAddress(signedOrderRight),
|
||||
leftSignature: signedOrderLeft.signature,
|
||||
rightSignature: signedOrderRight.signature,
|
||||
};
|
||||
|
@@ -1,26 +1,25 @@
|
||||
import { SignatureType } from '@0xproject/types';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
|
||||
import { SignatureType } from './types';
|
||||
|
||||
export const signingUtils = {
|
||||
signMessage(message: Buffer, privateKey: Buffer, signatureType: SignatureType): Buffer {
|
||||
if (signatureType === SignatureType.Ecrecover) {
|
||||
if (signatureType === SignatureType.EthSign) {
|
||||
const prefixedMessage = ethUtil.hashPersonalMessage(message);
|
||||
const ecSignature = ethUtil.ecsign(prefixedMessage, privateKey);
|
||||
const signature = Buffer.concat([
|
||||
ethUtil.toBuffer(signatureType),
|
||||
ethUtil.toBuffer(ecSignature.v),
|
||||
ecSignature.r,
|
||||
ecSignature.s,
|
||||
ethUtil.toBuffer(signatureType),
|
||||
]);
|
||||
return signature;
|
||||
} else if (signatureType === SignatureType.EIP712) {
|
||||
const ecSignature = ethUtil.ecsign(message, privateKey);
|
||||
const signature = Buffer.concat([
|
||||
ethUtil.toBuffer(signatureType),
|
||||
ethUtil.toBuffer(ecSignature.v),
|
||||
ecSignature.r,
|
||||
ecSignature.s,
|
||||
ethUtil.toBuffer(signatureType),
|
||||
]);
|
||||
return signature;
|
||||
} else {
|
||||
|
@@ -1,16 +1,21 @@
|
||||
import * as Web3 from 'web3';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
|
||||
import { TokenRegistryContract } from '../contract_wrappers/generated/token_registry';
|
||||
|
||||
import { Token } from './types';
|
||||
|
||||
import { constants } from './constants';
|
||||
|
||||
export class TokenRegWrapper {
|
||||
private _tokenReg: TokenRegistryContract;
|
||||
constructor(tokenRegContract: TokenRegistryContract) {
|
||||
private _web3Wrapper: Web3Wrapper;
|
||||
constructor(tokenRegContract: TokenRegistryContract, provider: Provider) {
|
||||
this._tokenReg = tokenRegContract;
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
}
|
||||
public async addTokenAsync(token: Token, from: string): Promise<string> {
|
||||
const tx = this._tokenReg.addToken.sendTransactionAsync(
|
||||
const txHash = await this._tokenReg.addToken.sendTransactionAsync(
|
||||
token.address as string,
|
||||
token.name,
|
||||
token.symbol,
|
||||
@@ -19,7 +24,8 @@ export class TokenRegWrapper {
|
||||
token.swarmHash,
|
||||
{ from },
|
||||
);
|
||||
return tx;
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
return txHash;
|
||||
}
|
||||
public async getTokenMetaDataAsync(tokenAddress: string): Promise<Token> {
|
||||
const data = await this._tokenReg.getTokenMetaData.callAsync(tokenAddress);
|
||||
|
@@ -1,32 +1,28 @@
|
||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { crypto, generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { SignatureType } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
|
||||
import { crypto } from './crypto';
|
||||
import { signingUtils } from './signing_utils';
|
||||
import { SignatureType, SignedTransaction } from './types';
|
||||
import { SignedTransaction } from './types';
|
||||
|
||||
export class TransactionFactory {
|
||||
private _signer: string;
|
||||
private _signerBuff: Buffer;
|
||||
private _exchangeAddress: string;
|
||||
private _privateKey: Buffer;
|
||||
constructor(privateKey: Buffer, exchangeAddress: string) {
|
||||
this._privateKey = privateKey;
|
||||
this._exchangeAddress = exchangeAddress;
|
||||
const signerBuff = ethUtil.privateToAddress(this._privateKey);
|
||||
this._signer = `0x${signerBuff.toString('hex')}`;
|
||||
this._signerBuff = ethUtil.privateToAddress(this._privateKey);
|
||||
}
|
||||
public newSignedTransaction(
|
||||
data: string,
|
||||
signatureType: SignatureType = SignatureType.Ecrecover,
|
||||
): SignedTransaction {
|
||||
public newSignedTransaction(data: string, signatureType: SignatureType = SignatureType.EthSign): SignedTransaction {
|
||||
const salt = generatePseudoRandomSalt();
|
||||
const txHash = crypto.solSHA3([this._exchangeAddress, salt, ethUtil.toBuffer(data)]);
|
||||
const txHash = crypto.solSHA3([this._exchangeAddress, this._signerBuff, salt, ethUtil.toBuffer(data)]);
|
||||
const signature = signingUtils.signMessage(txHash, this._privateKey, signatureType);
|
||||
const signedTx = {
|
||||
exchangeAddress: this._exchangeAddress,
|
||||
salt,
|
||||
signer: this._signer,
|
||||
signer: `0x${this._signerBuff.toString('hex')}`,
|
||||
data,
|
||||
signature: `0x${signature.toString('hex')}`,
|
||||
};
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { AbiDefinition, ContractAbi, Order } from '@0xproject/types';
|
||||
import { Order, OrderWithoutExchangeAddress } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { AbiDefinition, ContractAbi } from 'ethereum-types';
|
||||
|
||||
export interface ERC20BalancesByOwner {
|
||||
[ownerAddress: string]: {
|
||||
@@ -18,37 +19,31 @@ export interface SubmissionContractEventArgs {
|
||||
}
|
||||
|
||||
export interface BatchFillOrders {
|
||||
orders: Order[];
|
||||
orders: OrderWithoutExchangeAddress[];
|
||||
signatures: string[];
|
||||
takerAssetFillAmounts: BigNumber[];
|
||||
}
|
||||
|
||||
export interface MarketSellOrders {
|
||||
orders: Order[];
|
||||
orders: OrderWithoutExchangeAddress[];
|
||||
signatures: string[];
|
||||
takerAssetFillAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface MarketBuyOrders {
|
||||
orders: Order[];
|
||||
orders: OrderWithoutExchangeAddress[];
|
||||
signatures: string[];
|
||||
makerAssetFillAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface BatchCancelOrders {
|
||||
orders: Order[];
|
||||
orders: OrderWithoutExchangeAddress[];
|
||||
}
|
||||
|
||||
export interface CancelOrdersBefore {
|
||||
salt: BigNumber;
|
||||
}
|
||||
|
||||
export enum AssetProxyId {
|
||||
INVALID,
|
||||
ERC20,
|
||||
ERC721,
|
||||
}
|
||||
|
||||
export interface TransactionDataParams {
|
||||
name: string;
|
||||
abi: AbiDefinition[];
|
||||
@@ -111,16 +106,7 @@ export enum ContractName {
|
||||
DummyERC721Token = 'DummyERC721Token',
|
||||
TestLibBytes = 'TestLibBytes',
|
||||
Authorizable = 'Authorizable',
|
||||
}
|
||||
|
||||
export enum SignatureType {
|
||||
Illegal,
|
||||
Invalid,
|
||||
Caller,
|
||||
Ecrecover,
|
||||
EIP712,
|
||||
Trezor,
|
||||
Contract,
|
||||
Whitelist = 'Whitelist',
|
||||
}
|
||||
|
||||
export interface SignedTransaction {
|
||||
@@ -158,31 +144,14 @@ export interface OrderInfo {
|
||||
orderTakerAssetFilledAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface ERC20ProxyData {
|
||||
assetProxyId: AssetProxyId;
|
||||
tokenAddress: string;
|
||||
}
|
||||
|
||||
export interface ERC721ProxyData {
|
||||
assetProxyId: AssetProxyId;
|
||||
tokenAddress: string;
|
||||
tokenId: BigNumber;
|
||||
}
|
||||
|
||||
export interface ProxyData {
|
||||
assetProxyId: AssetProxyId;
|
||||
tokenAddress?: string;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export interface CancelOrder {
|
||||
order: Order;
|
||||
order: OrderWithoutExchangeAddress;
|
||||
takerAssetCancelAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface MatchOrder {
|
||||
left: Order;
|
||||
right: Order;
|
||||
left: OrderWithoutExchangeAddress;
|
||||
right: OrderWithoutExchangeAddress;
|
||||
leftSignature: string;
|
||||
rightSignature: string;
|
||||
}
|
||||
|
@@ -1,13 +1,13 @@
|
||||
import { devConstants, env, EnvVars, web3Factory } from '@0xproject/dev-utils';
|
||||
import { prependSubprovider } from '@0xproject/subproviders';
|
||||
import { Provider } from '@0xproject/types';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
|
||||
import { coverage } from './coverage';
|
||||
|
||||
export const txDefaults = {
|
||||
from: devConstants.TESTRPC_FIRST_ADDRESS,
|
||||
gas: devConstants.GAS_ESTIMATE,
|
||||
gas: devConstants.GAS_LIMIT,
|
||||
};
|
||||
const providerConfigs = { shouldUseInProcessGanache: true };
|
||||
export const provider = web3Factory.getRpcProvider(providerConfigs);
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as _ from 'lodash';
|
||||
@@ -8,12 +10,10 @@ import { DummyERC20TokenContract } from '../../src/contract_wrappers/generated/d
|
||||
import { DummyERC721TokenContract } from '../../src/contract_wrappers/generated/dummy_e_r_c721_token';
|
||||
import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c20_proxy';
|
||||
import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c721_proxy';
|
||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { AssetProxyId } from '../../src/utils/types';
|
||||
import { provider, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { LogWithDecodedArgs } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
import 'make-promises-safe';
|
||||
import * as Web3 from 'web3';
|
||||
@@ -35,6 +35,12 @@ describe('AssetProxyOwner', () => {
|
||||
let multiSig: AssetProxyOwnerContract;
|
||||
let multiSigWrapper: MultiSigWrapper;
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
after(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
before(async () => {
|
||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||
owners = [accounts[0], accounts[1]];
|
||||
@@ -60,8 +66,14 @@ describe('AssetProxyOwner', () => {
|
||||
SECONDS_TIME_LOCKED,
|
||||
);
|
||||
multiSigWrapper = new MultiSigWrapper(multiSig, provider);
|
||||
await erc20Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner });
|
||||
await erc721Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner });
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
|
@@ -83,7 +83,10 @@ describe('EtherToken', () => {
|
||||
|
||||
it('should convert ether tokens to ether with sufficient balance', async () => {
|
||||
const ethToDeposit = new BigNumber(Web3Wrapper.toWei(new BigNumber(1)));
|
||||
await etherToken.deposit.sendTransactionAsync({ value: ethToDeposit });
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await etherToken.deposit.sendTransactionAsync({ value: ethToDeposit }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const initEthTokenBalance = await etherToken.balanceOf.callAsync(account);
|
||||
const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account);
|
||||
const ethTokensToWithdraw = initEthTokenBalance;
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { LogWithDecodedArgs, SignedOrder } from '@0xproject/types';
|
||||
import { assetProxyUtils, crypto, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import ethUtil = require('ethereumjs-util');
|
||||
import 'make-promises-safe';
|
||||
|
||||
@@ -17,16 +19,13 @@ import {
|
||||
FillContractEventArgs,
|
||||
} from '../../src/contract_wrappers/generated/exchange';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { crypto } from '../../src/utils/crypto';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { orderUtils } from '../../src/utils/order_utils';
|
||||
import { AssetProxyId, ContractName, ERC20BalancesByOwner, ExchangeStatus } from '../../src/utils/types';
|
||||
import { ContractName, ERC20BalancesByOwner, ExchangeStatus } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -127,7 +126,6 @@ describe('Exchange core', () => {
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
|
||||
describe('fillOrder', () => {
|
||||
beforeEach(async () => {
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
@@ -141,7 +139,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
|
||||
|
||||
@@ -151,7 +149,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
const takerAssetFilledAmountAfter1 = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(takerAssetFilledAmountAfter1).to.be.bignumber.equal(fillTakerAssetAmount1);
|
||||
|
||||
@@ -161,7 +159,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
const takerAssetFilledAmountAfter2 = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(takerAssetFilledAmountAfter2).to.be.bignumber.equal(takerAssetFilledAmountAfter1);
|
||||
});
|
||||
@@ -173,7 +171,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
|
||||
|
||||
@@ -181,7 +179,7 @@ describe('Exchange core', () => {
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
|
||||
const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
|
||||
|
||||
@@ -226,7 +224,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
|
||||
|
||||
@@ -234,7 +232,7 @@ describe('Exchange core', () => {
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
|
||||
const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
|
||||
|
||||
@@ -279,7 +277,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
|
||||
|
||||
@@ -287,7 +285,7 @@ describe('Exchange core', () => {
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
|
||||
const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
|
||||
|
||||
@@ -333,7 +331,7 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
|
||||
|
||||
@@ -341,7 +339,7 @@ describe('Exchange core', () => {
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
|
||||
const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
|
||||
orderUtils.getOrderHashHex(signedOrder),
|
||||
orderHashUtils.getOrderHashHex(signedOrder),
|
||||
);
|
||||
const expectedMakerAmountBoughtAfter = takerAssetFillAmount.add(takerAssetFilledAmountBefore);
|
||||
expect(makerAmountBoughtAfter).to.be.bignumber.equal(expectedMakerAmountBoughtAfter);
|
||||
@@ -441,7 +439,7 @@ describe('Exchange core', () => {
|
||||
expect(expectedFilledTakerAssetAmount).to.be.bignumber.equal(logArgs.takerAssetFilledAmount);
|
||||
expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.makerFeePaid);
|
||||
expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.takerFeePaid);
|
||||
expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
|
||||
expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
|
||||
});
|
||||
|
||||
it('should throw when taker is specified and order is claimed by other', async () => {
|
||||
@@ -460,10 +458,11 @@ describe('Exchange core', () => {
|
||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
|
||||
});
|
||||
|
||||
const v = ethUtil.toBuffer(signedOrder.signature.slice(0, 4));
|
||||
const invalidR = ethUtil.sha3('invalidR');
|
||||
const invalidS = ethUtil.sha3('invalidS');
|
||||
const signatureTypeAndV = signedOrder.signature.slice(0, 6);
|
||||
const invalidSigBuff = Buffer.concat([ethUtil.toBuffer(signatureTypeAndV), invalidR, invalidS]);
|
||||
const signatureType = ethUtil.toBuffer(`0x${signedOrder.signature.slice(-2)}`);
|
||||
const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]);
|
||||
const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`;
|
||||
signedOrder.signature = invalidSigHex;
|
||||
return expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith(
|
||||
@@ -534,12 +533,6 @@ describe('Exchange core', () => {
|
||||
await expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith(
|
||||
constants.REVERT,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
|
||||
from: makerAddress,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if taker allowances are too low to fill order', async () => {
|
||||
@@ -555,12 +548,6 @@ describe('Exchange core', () => {
|
||||
await expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith(
|
||||
constants.REVERT,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
|
||||
from: takerAddress,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
});
|
||||
|
||||
it('should not change erc20Balances if an order is expired', async () => {
|
||||
@@ -651,7 +638,7 @@ describe('Exchange core', () => {
|
||||
expect(signedOrder.feeRecipientAddress).to.be.equal(logArgs.feeRecipientAddress);
|
||||
expect(signedOrder.makerAssetData).to.be.equal(logArgs.makerAssetData);
|
||||
expect(signedOrder.takerAssetData).to.be.equal(logArgs.takerAssetData);
|
||||
expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
|
||||
expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
|
||||
});
|
||||
|
||||
it('should log an error if already cancelled', async () => {
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as Web3 from 'web3';
|
||||
@@ -8,12 +10,10 @@ import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c2
|
||||
import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c721_proxy';
|
||||
import { TestAssetProxyDispatcherContract } from '../../src/contract_wrappers/generated/test_asset_proxy_dispatcher';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { AssetProxyId } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
@@ -7,11 +8,9 @@ import ethUtil = require('ethereumjs-util');
|
||||
import { TestLibsContract } from '../../src/contract_wrappers/generated/test_libs';
|
||||
import { addressUtils } from '../../src/utils/address_utils';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { orderUtils } from '../../src/utils/order_utils';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -49,7 +48,6 @@ describe('Exchange libs', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
@@ -59,19 +57,20 @@ describe('Exchange libs', () => {
|
||||
describe('getOrderSchema', () => {
|
||||
it('should output the correct order schema hash', async () => {
|
||||
const orderSchema = await libs.getOrderSchemaHash.callAsync();
|
||||
expect(orderUtils.getOrderSchemaHex()).to.be.equal(orderSchema);
|
||||
expect(orderHashUtils._getOrderSchemaHex()).to.be.equal(orderSchema);
|
||||
});
|
||||
});
|
||||
describe('getDomainSeparatorSchema', () => {
|
||||
it('should output the correct domain separator schema hash', async () => {
|
||||
const domainSeparatorSchema = await libs.getDomainSeparatorSchemaHash.callAsync();
|
||||
expect(orderUtils.getDomainSeparatorSchemaHex()).to.be.equal(domainSeparatorSchema);
|
||||
expect(orderHashUtils._getDomainSeparatorSchemaHex()).to.be.equal(domainSeparatorSchema);
|
||||
});
|
||||
});
|
||||
describe('getOrderHash', () => {
|
||||
it('should output the correct order hash', async () => {
|
||||
it('should output the correct orderHash', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
const orderHashHex = await libs.publicGetOrderHash.callAsync(signedOrder);
|
||||
expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex);
|
||||
expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { LogWithDecodedArgs, SignedOrder } from '@0xproject/types';
|
||||
import { assetProxyUtils, crypto } from '@0xproject/order-utils';
|
||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import ethUtil = require('ethereumjs-util');
|
||||
import * as _ from 'lodash';
|
||||
|
||||
@@ -17,17 +19,14 @@ import {
|
||||
FillContractEventArgs,
|
||||
} from '../../src/contract_wrappers/generated/exchange';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { crypto } from '../../src/utils/crypto';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
|
||||
import { MatchOrderTester } from '../../src/utils/match_order_tester';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { orderUtils } from '../../src/utils/order_utils';
|
||||
import {
|
||||
AssetProxyId,
|
||||
ContractName,
|
||||
ERC20BalancesByOwner,
|
||||
ERC721TokenIdsByOwner,
|
||||
@@ -36,8 +35,6 @@ import {
|
||||
} from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
import { MatchOrderTester } from '../../src/utils/match_order_tester';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
|
||||
import { SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
@@ -7,11 +8,9 @@ import ethUtil = require('ethereumjs-util');
|
||||
import { TestSignatureValidatorContract } from '../../src/contract_wrappers/generated/test_signature_validator';
|
||||
import { addressUtils } from '../../src/utils/address_utils';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { orderUtils } from '../../src/utils/order_utils';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -53,7 +52,6 @@ describe('MixinSignatureValidator', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
@@ -65,7 +63,7 @@ describe('MixinSignatureValidator', () => {
|
||||
});
|
||||
|
||||
it('should return true with a valid signature', async () => {
|
||||
const orderHashHex = orderUtils.getOrderHashHex(signedOrder);
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
|
||||
orderHashHex,
|
||||
signedOrder.makerAddress,
|
||||
@@ -75,16 +73,14 @@ describe('MixinSignatureValidator', () => {
|
||||
});
|
||||
|
||||
it('should return false with an invalid signature', async () => {
|
||||
const v = ethUtil.toBuffer(signedOrder.signature.slice(0, 4));
|
||||
const invalidR = ethUtil.sha3('invalidR');
|
||||
const invalidS = ethUtil.sha3('invalidS');
|
||||
const invalidSigBuff = Buffer.concat([
|
||||
ethUtil.toBuffer(signedOrder.signature.slice(0, 6)),
|
||||
invalidR,
|
||||
invalidS,
|
||||
]);
|
||||
const signatureType = ethUtil.toBuffer(`0x${signedOrder.signature.slice(-2)}`);
|
||||
const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]);
|
||||
const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`;
|
||||
signedOrder.signature = invalidSigHex;
|
||||
const orderHashHex = orderUtils.getOrderHashHex(signedOrder);
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
|
||||
orderHashHex,
|
||||
signedOrder.makerAddress,
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { Order, SignedOrder } from '@0xproject/types';
|
||||
import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { AssetProxyId, Order, OrderWithoutExchangeAddress, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
@@ -8,8 +9,8 @@ import * as Web3 from 'web3';
|
||||
import { DummyERC20TokenContract } from '../../src/contract_wrappers/generated/dummy_e_r_c20_token';
|
||||
import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c20_proxy';
|
||||
import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange';
|
||||
import { WhitelistContract } from '../../src/contract_wrappers/generated/whitelist';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
@@ -17,13 +18,7 @@ import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { orderUtils } from '../../src/utils/order_utils';
|
||||
import { TransactionFactory } from '../../src/utils/transaction_factory';
|
||||
import {
|
||||
AssetProxyId,
|
||||
ERC20BalancesByOwner,
|
||||
ExchangeStatus,
|
||||
SignatureType,
|
||||
SignedTransaction,
|
||||
} from '../../src/utils/types';
|
||||
import { ERC20BalancesByOwner, ExchangeStatus, SignedTransaction } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -46,7 +41,7 @@ describe('Exchange transactions', () => {
|
||||
let erc20Balances: ERC20BalancesByOwner;
|
||||
let signedOrder: SignedOrder;
|
||||
let signedTx: SignedTransaction;
|
||||
let order: Order;
|
||||
let orderWithoutExchangeAddress: OrderWithoutExchangeAddress;
|
||||
let orderFactory: OrderFactory;
|
||||
let makerTransactionFactory: TransactionFactory;
|
||||
let takerTransactionFactory: TransactionFactory;
|
||||
@@ -55,6 +50,8 @@ describe('Exchange transactions', () => {
|
||||
|
||||
let defaultMakerTokenAddress: string;
|
||||
let defaultTakerTokenAddress: string;
|
||||
let makerPrivateKey: Buffer;
|
||||
let takerPrivateKey: Buffer;
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
@@ -98,8 +95,8 @@ describe('Exchange transactions', () => {
|
||||
makerAssetData: assetProxyUtils.encodeERC20ProxyData(defaultMakerTokenAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20ProxyData(defaultTakerTokenAddress),
|
||||
};
|
||||
const makerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
|
||||
const takerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)];
|
||||
makerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
|
||||
takerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)];
|
||||
orderFactory = new OrderFactory(makerPrivateKey, defaultOrderParams);
|
||||
makerTransactionFactory = new TransactionFactory(makerPrivateKey, exchange.address);
|
||||
takerTransactionFactory = new TransactionFactory(takerPrivateKey, exchange.address);
|
||||
@@ -117,11 +114,11 @@ describe('Exchange transactions', () => {
|
||||
beforeEach(async () => {
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
order = orderUtils.getOrderStruct(signedOrder);
|
||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
|
||||
takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
const data = exchange.fillOrder.getABIEncodedTransactionData(
|
||||
order,
|
||||
orderWithoutExchangeAddress,
|
||||
takerAssetFillAmount,
|
||||
signedOrder.signature,
|
||||
);
|
||||
@@ -185,7 +182,7 @@ describe('Exchange transactions', () => {
|
||||
|
||||
describe('cancelOrder', () => {
|
||||
beforeEach(async () => {
|
||||
const data = exchange.cancelOrder.getABIEncodedTransactionData(order);
|
||||
const data = exchange.cancelOrder.getABIEncodedTransactionData(orderWithoutExchangeAddress);
|
||||
signedTx = makerTransactionFactory.newSignedTransaction(data);
|
||||
});
|
||||
|
||||
@@ -203,4 +200,131 @@ describe('Exchange transactions', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Whitelist', () => {
|
||||
let whitelist: WhitelistContract;
|
||||
let whitelistOrderFactory: OrderFactory;
|
||||
|
||||
before(async () => {
|
||||
whitelist = await WhitelistContract.deployFrom0xArtifactAsync(
|
||||
artifacts.Whitelist,
|
||||
provider,
|
||||
txDefaults,
|
||||
exchange.address,
|
||||
);
|
||||
const isApproved = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await exchange.setSignatureValidatorApproval.sendTransactionAsync(whitelist.address, isApproved, {
|
||||
from: takerAddress,
|
||||
}),
|
||||
);
|
||||
const defaultOrderParams = {
|
||||
...constants.STATIC_ORDER_PARAMS,
|
||||
senderAddress: whitelist.address,
|
||||
exchangeAddress: exchange.address,
|
||||
makerAddress,
|
||||
feeRecipientAddress,
|
||||
makerAssetData: assetProxyUtils.encodeERC20ProxyData(defaultMakerTokenAddress),
|
||||
takerAssetData: assetProxyUtils.encodeERC20ProxyData(defaultTakerTokenAddress),
|
||||
};
|
||||
whitelistOrderFactory = new OrderFactory(makerPrivateKey, defaultOrderParams);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
signedOrder = whitelistOrderFactory.newSignedOrder();
|
||||
erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
});
|
||||
|
||||
it('should revert if maker has not been whitelisted', async () => {
|
||||
const isApproved = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await whitelist.updateWhitelistStatus.sendTransactionAsync(takerAddress, isApproved, { from: owner }),
|
||||
);
|
||||
|
||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||
const salt = generatePseudoRandomSalt();
|
||||
return expect(
|
||||
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||
orderWithoutExchangeAddress,
|
||||
takerAssetFillAmount,
|
||||
salt,
|
||||
signedOrder.signature,
|
||||
{ from: takerAddress },
|
||||
),
|
||||
).to.be.rejectedWith(constants.REVERT);
|
||||
});
|
||||
|
||||
it('should revert if taker has not been whitelisted', async () => {
|
||||
const isApproved = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await whitelist.updateWhitelistStatus.sendTransactionAsync(makerAddress, isApproved, { from: owner }),
|
||||
);
|
||||
|
||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||
const salt = generatePseudoRandomSalt();
|
||||
return expect(
|
||||
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||
orderWithoutExchangeAddress,
|
||||
takerAssetFillAmount,
|
||||
salt,
|
||||
signedOrder.signature,
|
||||
{ from: takerAddress },
|
||||
),
|
||||
).to.be.rejectedWith(constants.REVERT);
|
||||
});
|
||||
|
||||
it('should fill the order if maker and taker have been whitelisted', async () => {
|
||||
const isApproved = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await whitelist.updateWhitelistStatus.sendTransactionAsync(makerAddress, isApproved, { from: owner }),
|
||||
);
|
||||
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await whitelist.updateWhitelistStatus.sendTransactionAsync(takerAddress, isApproved, { from: owner }),
|
||||
);
|
||||
|
||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||
const salt = generatePseudoRandomSalt();
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||
orderWithoutExchangeAddress,
|
||||
takerAssetFillAmount,
|
||||
salt,
|
||||
signedOrder.signature,
|
||||
{ from: takerAddress },
|
||||
),
|
||||
);
|
||||
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
|
||||
const makerAssetFillAmount = signedOrder.makerAssetAmount;
|
||||
const makerFeePaid = signedOrder.makerFee;
|
||||
const takerFeePaid = signedOrder.takerFee;
|
||||
|
||||
expect(newBalances[makerAddress][defaultMakerTokenAddress]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][defaultMakerTokenAddress].minus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[makerAddress][defaultTakerTokenAddress]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][defaultTakerTokenAddress].add(takerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][zrxToken.address].minus(makerFeePaid),
|
||||
);
|
||||
expect(newBalances[takerAddress][defaultTakerTokenAddress]).to.be.bignumber.equal(
|
||||
erc20Balances[takerAddress][defaultTakerTokenAddress].minus(takerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[takerAddress][defaultMakerTokenAddress]).to.be.bignumber.equal(
|
||||
erc20Balances[takerAddress][defaultMakerTokenAddress].add(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[takerAddress][zrxToken.address].minus(takerFeePaid),
|
||||
);
|
||||
expect(newBalances[feeRecipientAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[feeRecipientAddress][zrxToken.address].add(makerFeePaid.add(takerFeePaid)),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
|
||||
import { SignedOrder } from '@0xproject/types';
|
||||
import { assetProxyUtils } from '@0xproject/order-utils';
|
||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
@@ -14,14 +15,13 @@ import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c
|
||||
import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange';
|
||||
import { TokenRegistryContract } from '../../src/contract_wrappers/generated/token_registry';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { AssetProxyId, ERC20BalancesByOwner } from '../../src/utils/types';
|
||||
import { ERC20BalancesByOwner } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
|
||||
import { LogWithDecodedArgs, TransactionReceiptWithDecodedLogs } from '@0xproject/types';
|
||||
import { AssetProxyId } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import BN = require('bn.js');
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import ethUtil = require('ethereumjs-util');
|
||||
import * as Web3 from 'web3';
|
||||
|
||||
@@ -11,7 +12,6 @@ import { TestLibBytesContract } from '../../src/contract_wrappers/generated/test
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { AssetProxyId } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -22,6 +22,7 @@ describe('LibBytes', () => {
|
||||
let owner: string;
|
||||
let libBytes: TestLibBytesContract;
|
||||
const byteArrayShorterThan32Bytes = '0x012345';
|
||||
const byteArrayShorterThan20Bytes = byteArrayShorterThan32Bytes;
|
||||
const byteArrayLongerThan32Bytes =
|
||||
'0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
||||
const byteArrayLongerThan32BytesFirstBytesSwapped =
|
||||
@@ -60,6 +61,36 @@ describe('LibBytes', () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
|
||||
describe('popByte', () => {
|
||||
it('should revert if length is 0', async () => {
|
||||
return expect(libBytes.publicPopByte.callAsync(constants.NULL_BYTES)).to.be.rejectedWith(constants.REVERT);
|
||||
});
|
||||
|
||||
it('should pop the last byte from the input and return it', async () => {
|
||||
const [newBytes, poppedByte] = await libBytes.publicPopByte.callAsync(byteArrayLongerThan32Bytes);
|
||||
const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -2);
|
||||
const expectedPoppedByte = `0x${byteArrayLongerThan32Bytes.slice(-2)}`;
|
||||
expect(newBytes).to.equal(expectedNewBytes);
|
||||
expect(poppedByte).to.equal(expectedPoppedByte);
|
||||
});
|
||||
});
|
||||
|
||||
describe('popAddress', () => {
|
||||
it('should revert if length is less than 20', async () => {
|
||||
return expect(libBytes.publicPopAddress.callAsync(byteArrayShorterThan20Bytes)).to.be.rejectedWith(
|
||||
constants.REVERT,
|
||||
);
|
||||
});
|
||||
|
||||
it('should pop the last 20 bytes from the input and return it', async () => {
|
||||
const [newBytes, poppedAddress] = await libBytes.publicPopAddress.callAsync(byteArrayLongerThan32Bytes);
|
||||
const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -40);
|
||||
const expectedPoppedAddress = `0x${byteArrayLongerThan32Bytes.slice(-40)}`;
|
||||
expect(newBytes).to.equal(expectedNewBytes);
|
||||
expect(poppedAddress).to.equal(expectedPoppedAddress);
|
||||
});
|
||||
});
|
||||
|
||||
describe('areBytesEqual', () => {
|
||||
it('should return true if byte arrays are equal (both arrays < 32 bytes)', async () => {
|
||||
const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync(
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { BlockchainLifecycle, web3Factory } from '@0xproject/dev-utils';
|
||||
import { LogWithDecodedArgs } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
import 'make-promises-safe';
|
||||
import * as Web3 from 'web3';
|
||||
@@ -26,6 +26,12 @@ describe('MultiSigWalletWithTimeLock', () => {
|
||||
const REQUIRED_APPROVALS = new BigNumber(2);
|
||||
const SECONDS_TIME_LOCKED = new BigNumber(1000000);
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
after(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
before(async () => {
|
||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||
owners = [accounts[0], accounts[1]];
|
||||
|
@@ -23,6 +23,7 @@ describe('TokenRegistry', () => {
|
||||
let notOwner: string;
|
||||
let tokenReg: TokenRegistryContract;
|
||||
let tokenRegWrapper: TokenRegWrapper;
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
@@ -34,7 +35,7 @@ describe('TokenRegistry', () => {
|
||||
owner = accounts[0];
|
||||
notOwner = accounts[1];
|
||||
tokenReg = await TokenRegistryContract.deployFrom0xArtifactAsync(artifacts.TokenRegistry, provider, txDefaults);
|
||||
tokenRegWrapper = new TokenRegWrapper(tokenReg);
|
||||
tokenRegWrapper = new TokenRegWrapper(tokenReg, provider);
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// import { ECSignature, SignedOrder, ZeroEx } from '0x.js';
|
||||
// import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
|
||||
// import { ExchangeContractErrs } from '@0xproject/types';
|
||||
// import { ExchangeContractErrs } from 'ethereum-types';
|
||||
// import { BigNumber } from '@0xproject/utils';
|
||||
// import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
// import * as chai from 'chai';
|
||||
|
@@ -64,7 +64,10 @@ describe('UnlimitedAllowanceToken', () => {
|
||||
const receiver = spender;
|
||||
const initOwnerBalance = await token.balanceOf.callAsync(owner);
|
||||
const amountToTransfer = new BigNumber(1);
|
||||
await token.transfer.sendTransactionAsync(receiver, amountToTransfer, { from: owner });
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await token.transfer.sendTransactionAsync(receiver, amountToTransfer, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const finalOwnerBalance = await token.balanceOf.callAsync(owner);
|
||||
const finalReceiverBalance = await token.balanceOf.callAsync(receiver);
|
||||
|
||||
@@ -86,7 +89,10 @@ describe('UnlimitedAllowanceToken', () => {
|
||||
it('should throw if owner has insufficient balance', async () => {
|
||||
const ownerBalance = await token.balanceOf.callAsync(owner);
|
||||
const amountToTransfer = ownerBalance.plus(1);
|
||||
await token.approve.sendTransactionAsync(spender, amountToTransfer, { from: owner });
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await token.approve.sendTransactionAsync(spender, amountToTransfer, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
return expect(
|
||||
token.transferFrom.callAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
@@ -121,11 +127,17 @@ describe('UnlimitedAllowanceToken', () => {
|
||||
const initOwnerBalance = await token.balanceOf.callAsync(owner);
|
||||
const amountToTransfer = initOwnerBalance;
|
||||
const initSpenderAllowance = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
|
||||
await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner });
|
||||
await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
|
||||
});
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
const newSpenderAllowance = await token.allowance.callAsync(owner, spender);
|
||||
expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
|
||||
@@ -135,11 +147,17 @@ describe('UnlimitedAllowanceToken', () => {
|
||||
const initOwnerBalance = await token.balanceOf.callAsync(owner);
|
||||
const amountToTransfer = initOwnerBalance;
|
||||
const initSpenderAllowance = initOwnerBalance;
|
||||
await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner });
|
||||
await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
|
||||
});
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
const newOwnerBalance = await token.balanceOf.callAsync(owner);
|
||||
const newSpenderBalance = await token.balanceOf.callAsync(spender);
|
||||
@@ -152,11 +170,17 @@ describe('UnlimitedAllowanceToken', () => {
|
||||
const initOwnerBalance = await token.balanceOf.callAsync(owner);
|
||||
const amountToTransfer = initOwnerBalance;
|
||||
const initSpenderAllowance = initOwnerBalance;
|
||||
await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner });
|
||||
await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
|
||||
});
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
const newSpenderAllowance = await token.allowance.callAsync(owner, spender);
|
||||
expect(newSpenderAllowance).to.be.bignumber.equal(0);
|
||||
|
@@ -46,6 +46,7 @@
|
||||
"dependencies": {
|
||||
"@0xproject/subproviders": "^0.10.2",
|
||||
"@0xproject/types": "^0.7.0",
|
||||
"ethereum-types": "^0.0.1",
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/web3-wrapper": "^0.6.4",
|
||||
"lodash": "^4.17.4",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
export const constants = {
|
||||
RPC_URL: 'http://localhost:8545',
|
||||
RPC_PORT: 8545,
|
||||
GAS_ESTIMATE: 5000000,
|
||||
GAS_LIMIT: 7000000,
|
||||
TESTRPC_FIRST_ADDRESS: '0x5409ed021d9299bf6814279a6a1411a7e866a631',
|
||||
};
|
||||
|
@@ -7,7 +7,7 @@ import ProviderEngine = require('web3-provider-engine');
|
||||
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
|
||||
|
||||
import { EmptyWalletSubprovider, FakeGasEstimateSubprovider, GanacheSubprovider } from '@0xproject/subproviders';
|
||||
import { Provider } from '@0xproject/types';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as fs from 'fs';
|
||||
import * as _ from 'lodash';
|
||||
import * as process from 'process';
|
||||
@@ -28,7 +28,7 @@ export const web3Factory = {
|
||||
if (!hasAddresses) {
|
||||
provider.addProvider(new EmptyWalletSubprovider());
|
||||
}
|
||||
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
|
||||
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_LIMIT));
|
||||
const logger = {
|
||||
log: (arg: any) => {
|
||||
fs.appendFileSync('ganache.log', `${arg}\n`);
|
||||
@@ -41,6 +41,7 @@ export const web3Factory = {
|
||||
}
|
||||
provider.addProvider(
|
||||
new GanacheSubprovider({
|
||||
gasLimit: constants.GAS_LIMIT,
|
||||
logger,
|
||||
verbose: env.parseBoolean(EnvVars.VerboseGanache),
|
||||
port: 8545,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { BlockParamLiteral } from '@0xproject/types';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import { BlockParamLiteral } from 'ethereum-types';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { BlockParamLiteral } from '@0xproject/types';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import { BlockParamLiteral } from 'ethereum-types';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
|
6
packages/ethereum-types/.npmignore
Normal file
6
packages/ethereum-types/.npmignore
Normal file
@@ -0,0 +1,6 @@
|
||||
.*
|
||||
yarn-error.log
|
||||
/scripts/
|
||||
/src/
|
||||
tsconfig.json
|
||||
/lib/monorepo_scripts/
|
11
packages/ethereum-types/CHANGELOG.json
Normal file
11
packages/ethereum-types/CHANGELOG.json
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"version": "0.0.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Initial publish",
|
||||
"pr": "642"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
61
packages/ethereum-types/README.md
Normal file
61
packages/ethereum-types/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
## ethereum-types
|
||||
|
||||
Typescript types shared across Ethereum-related packages/libraries/tools.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add -D ethereum-types
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
import { TransactionReceipt, TxData, TxDataPayable } from 'ethereum-types';
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository.
|
||||
|
||||
Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
|
||||
|
||||
### Install dependencies
|
||||
|
||||
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
|
||||
|
||||
```bash
|
||||
yarn config set workspaces-experimental true
|
||||
```
|
||||
|
||||
Then install dependencies
|
||||
|
||||
```bash
|
||||
yarn install
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
|
||||
|
||||
```bash
|
||||
PKG=ethereum-types yarn build
|
||||
```
|
||||
|
||||
Or continuously rebuild on change:
|
||||
|
||||
```bash
|
||||
PKG=ethereum-types yarn watch
|
||||
```
|
||||
|
||||
### Clean
|
||||
|
||||
```bash
|
||||
yarn clean
|
||||
```
|
||||
|
||||
### Lint
|
||||
|
||||
```bash
|
||||
yarn lint
|
||||
```
|
42
packages/ethereum-types/package.json
Normal file
42
packages/ethereum-types/package.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "ethereum-types",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
"description": "Ethereum types",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"scripts": {
|
||||
"watch": "tsc -w",
|
||||
"build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
|
||||
"clean": "shx rm -rf lib scripts",
|
||||
"lint": "tslint --project .",
|
||||
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/0xProject/0x-monorepo.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/0xProject/0x-monorepo/issues"
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/ethereum-types/README.md",
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.1.20",
|
||||
"@0xproject/tslint-config": "^0.4.18",
|
||||
"copyfiles": "^1.2.0",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
"shx": "^0.2.2",
|
||||
"tslint": "5.8.0",
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^8.0.53",
|
||||
"bignumber.js": "~4.1.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
6
packages/ethereum-types/src/globals.d.ts
vendored
Normal file
6
packages/ethereum-types/src/globals.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
declare module '*.json' {
|
||||
const json: any;
|
||||
/* tslint:disable */
|
||||
export default json;
|
||||
/* tslint:enable */
|
||||
}
|
281
packages/ethereum-types/src/index.ts
Normal file
281
packages/ethereum-types/src/index.ts
Normal file
@@ -0,0 +1,281 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
|
||||
export type JSONRPCErrorCallback = (err: Error | null, result?: JSONRPCResponsePayload) => void;
|
||||
|
||||
/**
|
||||
* Do not create your own provider. Use an existing provider from a Web3 or ProviderEngine library
|
||||
* Read more about Providers in the 0x wiki.
|
||||
*/
|
||||
export interface Provider {
|
||||
sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): void;
|
||||
}
|
||||
|
||||
export type ContractAbi = AbiDefinition[];
|
||||
|
||||
export type AbiDefinition = FunctionAbi | EventAbi;
|
||||
|
||||
export type FunctionAbi = MethodAbi | ConstructorAbi | FallbackAbi;
|
||||
|
||||
export type ConstructorStateMutability = 'nonpayable' | 'payable';
|
||||
export type StateMutability = 'pure' | 'view' | ConstructorStateMutability;
|
||||
|
||||
export interface MethodAbi {
|
||||
type: AbiType.Function;
|
||||
name: string;
|
||||
inputs: DataItem[];
|
||||
outputs: DataItem[];
|
||||
constant: boolean;
|
||||
stateMutability: StateMutability;
|
||||
payable: boolean;
|
||||
}
|
||||
|
||||
export interface ConstructorAbi {
|
||||
type: AbiType.Constructor;
|
||||
inputs: DataItem[];
|
||||
payable: boolean;
|
||||
stateMutability: ConstructorStateMutability;
|
||||
}
|
||||
|
||||
export interface FallbackAbi {
|
||||
type: AbiType.Fallback;
|
||||
payable: boolean;
|
||||
}
|
||||
|
||||
export interface EventParameter extends DataItem {
|
||||
indexed: boolean;
|
||||
}
|
||||
|
||||
export interface EventAbi {
|
||||
type: AbiType.Event;
|
||||
name: string;
|
||||
inputs: EventParameter[];
|
||||
anonymous: boolean;
|
||||
}
|
||||
|
||||
export interface DataItem {
|
||||
name: string;
|
||||
type: string;
|
||||
components?: DataItem[];
|
||||
}
|
||||
|
||||
export enum OpCode {
|
||||
DelegateCall = 'DELEGATECALL',
|
||||
Revert = 'REVERT',
|
||||
Create = 'CREATE',
|
||||
Stop = 'STOP',
|
||||
Invalid = 'INVALID',
|
||||
CallCode = 'CALLCODE',
|
||||
StaticCall = 'STATICCALL',
|
||||
Return = 'RETURN',
|
||||
Call = 'CALL',
|
||||
SelfDestruct = 'SELFDESTRUCT',
|
||||
}
|
||||
|
||||
export interface StructLog {
|
||||
depth: number;
|
||||
error: string;
|
||||
gas: number;
|
||||
gasCost: number;
|
||||
memory: string[];
|
||||
op: OpCode;
|
||||
pc: number;
|
||||
stack: string[];
|
||||
storage: { [location: string]: string };
|
||||
}
|
||||
|
||||
export interface TransactionTrace {
|
||||
gas: number;
|
||||
returnValue: any;
|
||||
structLogs: StructLog[];
|
||||
}
|
||||
|
||||
export type Unit =
|
||||
| 'kwei'
|
||||
| 'ada'
|
||||
| 'mwei'
|
||||
| 'babbage'
|
||||
| 'gwei'
|
||||
| 'shannon'
|
||||
| 'szabo'
|
||||
| 'finney'
|
||||
| 'ether'
|
||||
| 'kether'
|
||||
| 'grand'
|
||||
| 'einstein'
|
||||
| 'mether'
|
||||
| 'gether'
|
||||
| 'tether';
|
||||
|
||||
export interface JSONRPCRequestPayload {
|
||||
params: any[];
|
||||
method: string;
|
||||
id: number;
|
||||
jsonrpc: string;
|
||||
}
|
||||
|
||||
export interface JSONRPCResponsePayload {
|
||||
result: any;
|
||||
id: number;
|
||||
jsonrpc: string;
|
||||
}
|
||||
|
||||
export interface AbstractBlock {
|
||||
number: number | null;
|
||||
hash: string | null;
|
||||
parentHash: string;
|
||||
nonce: string | null;
|
||||
sha3Uncles: string;
|
||||
logsBloom: string | null;
|
||||
transactionsRoot: string;
|
||||
stateRoot: string;
|
||||
miner: string;
|
||||
difficulty: BigNumber;
|
||||
totalDifficulty: BigNumber;
|
||||
extraData: string;
|
||||
size: number;
|
||||
gasLimit: number;
|
||||
gasUsed: number;
|
||||
timestamp: number;
|
||||
uncles: string[];
|
||||
}
|
||||
|
||||
export interface BlockWithoutTransactionData extends AbstractBlock {
|
||||
transactions: string[];
|
||||
}
|
||||
|
||||
export interface BlockWithTransactionData extends AbstractBlock {
|
||||
transactions: Transaction[];
|
||||
}
|
||||
|
||||
export interface Transaction {
|
||||
hash: string;
|
||||
nonce: number;
|
||||
blockHash: string | null;
|
||||
blockNumber: number | null;
|
||||
transactionIndex: number | null;
|
||||
from: string;
|
||||
to: string | null;
|
||||
value: BigNumber;
|
||||
gasPrice: BigNumber;
|
||||
gas: number;
|
||||
input: string;
|
||||
}
|
||||
|
||||
export interface CallTxDataBase {
|
||||
to?: string;
|
||||
value?: number | string | BigNumber;
|
||||
gas?: number | string | BigNumber;
|
||||
gasPrice?: number | string | BigNumber;
|
||||
data?: string;
|
||||
nonce?: number;
|
||||
}
|
||||
|
||||
export interface TxData extends CallTxDataBase {
|
||||
from: string;
|
||||
}
|
||||
|
||||
export interface CallData extends CallTxDataBase {
|
||||
from?: string;
|
||||
}
|
||||
|
||||
export interface FilterObject {
|
||||
fromBlock?: number | string;
|
||||
toBlock?: number | string;
|
||||
address?: string;
|
||||
topics?: LogTopic[];
|
||||
}
|
||||
|
||||
export type LogTopic = null | string | string[];
|
||||
|
||||
export interface DecodedLogEntry<A> extends LogEntry {
|
||||
event: string;
|
||||
args: A;
|
||||
}
|
||||
|
||||
export interface DecodedLogEntryEvent<A> extends DecodedLogEntry<A> {
|
||||
removed: boolean;
|
||||
}
|
||||
|
||||
export interface LogEntryEvent extends LogEntry {
|
||||
removed: boolean;
|
||||
}
|
||||
|
||||
export interface LogEntry {
|
||||
logIndex: number | null;
|
||||
transactionIndex: number | null;
|
||||
transactionHash: string;
|
||||
blockHash: string | null;
|
||||
blockNumber: number | null;
|
||||
address: string;
|
||||
data: string;
|
||||
topics: string[];
|
||||
}
|
||||
|
||||
export interface TxDataPayable extends TxData {
|
||||
value?: BigNumber;
|
||||
}
|
||||
|
||||
export interface TransactionReceipt {
|
||||
blockHash: string;
|
||||
blockNumber: number;
|
||||
transactionHash: string;
|
||||
transactionIndex: number;
|
||||
from: string;
|
||||
to: string;
|
||||
status: null | string | 0 | 1;
|
||||
cumulativeGasUsed: number;
|
||||
gasUsed: number;
|
||||
contractAddress: string | null;
|
||||
logs: LogEntry[];
|
||||
}
|
||||
|
||||
export enum AbiType {
|
||||
Function = 'function',
|
||||
Constructor = 'constructor',
|
||||
Event = 'event',
|
||||
Fallback = 'fallback',
|
||||
}
|
||||
|
||||
export type ContractEventArg = string | BigNumber | number | boolean;
|
||||
|
||||
export interface DecodedLogArgs {
|
||||
[argName: string]: ContractEventArg;
|
||||
}
|
||||
|
||||
export interface LogWithDecodedArgs<ArgsType extends DecodedLogArgs> extends DecodedLogEntry<ArgsType> {}
|
||||
export type RawLog = LogEntry;
|
||||
|
||||
export enum BlockParamLiteral {
|
||||
Earliest = 'earliest',
|
||||
Latest = 'latest',
|
||||
Pending = 'pending',
|
||||
}
|
||||
|
||||
export type BlockParam = BlockParamLiteral | number;
|
||||
|
||||
export interface RawLogEntry {
|
||||
logIndex: string | null;
|
||||
transactionIndex: string | null;
|
||||
transactionHash: string;
|
||||
blockHash: string | null;
|
||||
blockNumber: string | null;
|
||||
address: string;
|
||||
data: string;
|
||||
topics: string[];
|
||||
}
|
||||
|
||||
export enum SolidityTypes {
|
||||
Address = 'address',
|
||||
Uint256 = 'uint256',
|
||||
Uint8 = 'uint8',
|
||||
Uint = 'uint',
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains the logs returned by a TransactionReceipt. We attempt to decode the
|
||||
* logs using AbiDecoder. If we have the logs corresponding ABI, we decode it,
|
||||
* otherwise we don't.
|
||||
*/
|
||||
export interface TransactionReceiptWithDecodedLogs extends TransactionReceipt {
|
||||
logs: Array<LogWithDecodedArgs<DecodedLogArgs> | LogEntry>;
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
import { postpublishUtils } from '@0xproject/monorepo-scripts';
|
||||
|
||||
import * as packageJSON from '../package.json';
|
||||
import * as tsConfigJSON from '../tsconfig.json';
|
||||
|
||||
const cwd = `${__dirname}/..`;
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
|
8
packages/ethereum-types/tsconfig.json
Normal file
8
packages/ethereum-types/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"typeRoots": ["../../node_modules/@types"],
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
3
packages/ethereum-types/tslint.json
Normal file
3
packages/ethereum-types/tslint.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": ["@0xproject/tslint-config"]
|
||||
}
|
@@ -37,8 +37,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/base-contract": "^0.3.2",
|
||||
"@0xproject/order-utils": "^0.0.5",
|
||||
"@0xproject/order-utils": "0.0.5",
|
||||
"@0xproject/types": "0.7.0",
|
||||
"ethereum-types": "^0.0.1",
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"@0xproject/web3-wrapper": "^0.6.4",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/json-schemas",
|
||||
"version": "0.7.24",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -27,7 +27,8 @@
|
||||
"assets": [],
|
||||
"docPublishConfigs": {
|
||||
"extraFileIncludes": [
|
||||
"../types/src/index.ts"
|
||||
"../types/src/index.ts",
|
||||
"../ethereum-types/src/index.ts"
|
||||
],
|
||||
"s3BucketPath": "s3://doc-jsons/json-schemas/",
|
||||
"s3StagingBucketPath": "s3://staging-doc-jsons/json-schemas/"
|
||||
|
20
packages/json-schemas/schemas/ec_signature_schema.ts
Normal file
20
packages/json-schemas/schemas/ec_signature_schema.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
export const ecSignatureParameterSchema = {
|
||||
id: '/ECSignatureParameter',
|
||||
type: 'string',
|
||||
pattern: '^0[xX][0-9A-Fa-f]{64}$',
|
||||
};
|
||||
|
||||
export const ecSignatureSchema = {
|
||||
id: '/ECSignature',
|
||||
properties: {
|
||||
v: {
|
||||
type: 'number',
|
||||
minimum: 27,
|
||||
maximum: 28,
|
||||
},
|
||||
r: { $ref: '/ECSignatureParameter' },
|
||||
s: { $ref: '/ECSignatureParameter' },
|
||||
},
|
||||
required: ['v', 'r', 's'],
|
||||
type: 'object',
|
||||
};
|
@@ -5,11 +5,13 @@ export const orderSchema = {
|
||||
takerAddress: { $ref: '/Address' },
|
||||
makerFee: { $ref: '/Number' },
|
||||
takerFee: { $ref: '/Number' },
|
||||
senderAddress: { $ref: '/Address' },
|
||||
makerAssetAmount: { $ref: '/Number' },
|
||||
takerAssetAmount: { $ref: '/Number' },
|
||||
makerAssetData: { $ref: '/Hex' },
|
||||
takerAssetData: { $ref: '/Hex' },
|
||||
salt: { $ref: '/Number' },
|
||||
exchangeAddress: { $ref: '/Address' },
|
||||
feeRecipientAddress: { $ref: '/Address' },
|
||||
expirationTimeSeconds: { $ref: '/Number' },
|
||||
},
|
||||
@@ -18,11 +20,13 @@ export const orderSchema = {
|
||||
'takerAddress',
|
||||
'makerFee',
|
||||
'takerFee',
|
||||
'senderAddress',
|
||||
'makerAssetAmount',
|
||||
'takerAssetAmount',
|
||||
'makerAssetData',
|
||||
'takerAssetData',
|
||||
'salt',
|
||||
'exchangeAddress',
|
||||
'feeRecipientAddress',
|
||||
'expirationTimeSeconds',
|
||||
],
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { addressSchema, hexSchema, numberSchema } from '../schemas/basic_type_schemas';
|
||||
import { blockParamSchema, blockRangeSchema } from '../schemas/block_range_schema';
|
||||
import { ecSignatureSchema } from '../schemas/ec_signature_schema';
|
||||
import { indexFilterValuesSchema } from '../schemas/index_filter_values_schema';
|
||||
import { orderCancellationRequestsSchema } from '../schemas/order_cancel_schema';
|
||||
import { orderFillOrKillRequestsSchema } from '../schemas/order_fill_or_kill_requests_schema';
|
||||
@@ -31,6 +32,7 @@ export const schemas = {
|
||||
numberSchema,
|
||||
addressSchema,
|
||||
hexSchema,
|
||||
ecSignatureSchema,
|
||||
indexFilterValuesSchema,
|
||||
orderCancellationRequestsSchema,
|
||||
orderFillOrKillRequestsSchema,
|
||||
|
@@ -171,6 +171,7 @@ describe('Schema', () => {
|
||||
const order = {
|
||||
makerAddress: NULL_ADDRESS,
|
||||
takerAddress: NULL_ADDRESS,
|
||||
senderAddress: NULL_ADDRESS,
|
||||
makerFee: '1',
|
||||
takerFee: '2',
|
||||
makerAssetAmount: '1',
|
||||
@@ -179,6 +180,7 @@ describe('Schema', () => {
|
||||
takerAssetData: NULL_ADDRESS,
|
||||
salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
|
||||
feeRecipientAddress: NULL_ADDRESS,
|
||||
exchangeAddress: NULL_ADDRESS,
|
||||
expirationTimeSeconds: '42',
|
||||
};
|
||||
describe('#orderSchema', () => {
|
||||
|
@@ -35,6 +35,7 @@
|
||||
"@0xproject/types": "^0.7.0",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"@0xproject/web3-wrapper": "^0.6.4",
|
||||
"ethereum-types": "^0.0.1",
|
||||
"ethers": "^3.0.15",
|
||||
"lodash": "^4.17.4",
|
||||
"web3-provider-engine": "^14.0.4"
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { BlockchainLifecycle, devConstants } from '@0xproject/dev-utils';
|
||||
import { ContractArtifact } from '@0xproject/sol-compiler';
|
||||
import { LogWithDecodedArgs } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import 'make-promises-safe';
|
||||
|
||||
import * as MetacoinArtifact from '../artifacts/Metacoin.json';
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
648
packages/migrations/artifacts/2.0.0/ERC20Proxy.json
vendored
648
packages/migrations/artifacts/2.0.0/ERC20Proxy.json
vendored
File diff suppressed because one or more lines are too long
675
packages/migrations/artifacts/2.0.0/ERC721Proxy.json
vendored
675
packages/migrations/artifacts/2.0.0/ERC721Proxy.json
vendored
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user