Merge branch 'development' into sol-doc

This commit is contained in:
F. Eugene Aumson 2018-09-11 19:00:11 -04:00 committed by GitHub
commit cbb5a425df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
259 changed files with 29841 additions and 108076 deletions

5
.gitignore vendored
View File

@ -88,7 +88,7 @@ packages/0x.js/src/artifacts/
packages/order-utils/src/artifacts/ packages/order-utils/src/artifacts/
# unstable generated contract artifacts: # unstable generated contract artifacts:
packages/migrations/artifacts/2.0.0/ packages/migrations/artifacts/development/
# generated contract watcher # generated contract watcher
packages/0x.js/src/generated_contract_wrappers/ packages/0x.js/src/generated_contract_wrappers/
@ -99,8 +99,9 @@ packages/fill-scenarios/src/generated_contract_wrappers/
packages/order-watcher/src/generated_contract_wrappers/ packages/order-watcher/src/generated_contract_wrappers/
packages/order-utils/src/generated_contract_wrappers/ packages/order-utils/src/generated_contract_wrappers/
packages/migrations/src/1.0.0/contract_wrappers packages/migrations/src/1.0.0/contract_wrappers
packages/migrations/src/2.0.0-testnet/contract_wrappers
packages/migrations/src/2.0.0/contract_wrappers packages/migrations/src/2.0.0/contract_wrappers
packages/migrations/src/2.0.0-beta-testnet/contract_wrappers packages/migrations/src/development/contract_wrappers
# solc-bin in sol-compiler # solc-bin in sol-compiler
packages/sol-compiler/solc_bin/ packages/sol-compiler/solc_bin/

View File

@ -8,8 +8,8 @@ lib
/packages/order-watcher/src/generated_contract_wrappers/ /packages/order-watcher/src/generated_contract_wrappers/
/packages/order-utils/src/generated_contract_wrappers/ /packages/order-utils/src/generated_contract_wrappers/
/packages/migrations/src/1.0.0/contract_wrappers /packages/migrations/src/1.0.0/contract_wrappers
/packages/migrations/src/2.0.0-testnet/contract_wrappers
/packages/migrations/src/2.0.0/contract_wrappers /packages/migrations/src/2.0.0/contract_wrappers
/packages/migrations/src/2.0.0-beta-testnet/contract_wrappers
/packages/0x.js/src/artifacts /packages/0x.js/src/artifacts
/packages/contracts/src/artifacts /packages/contracts/src/artifacts
/packages/contract-wrappers/src/artifacts /packages/contract-wrappers/src/artifacts
@ -19,7 +19,9 @@ lib
/packages/contract-wrappers/test/artifacts /packages/contract-wrappers/test/artifacts
/packages/order-watcher/test/artifacts /packages/order-watcher/test/artifacts
/packages/migrations/artifacts/1.0.0 /packages/migrations/artifacts/1.0.0
/packages/migrations/artifacts/2.0.0-testnet
/packages/migrations/artifacts/2.0.0 /packages/migrations/artifacts/2.0.0
/packages/migrations/artifacts/2.0.0-beta-testnet /packages/migrations/artifacts/development
package.json package.json
scripts/postpublish_utils.js scripts/postpublish_utils.js
packages/sol-cov/test/fixtures/artifacts

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"version": "1.0.1-rc.6", "version": "1.0.1-rc.6",
"changes": [ "changes": [

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.1 - _September 5, 2018_
* Dependencies updated
## v1.0.1-rc.6 - _August 27, 2018_ ## v1.0.1-rc.6 - _August 27, 2018_
* Fix missing `BlockParamLiteral` type import issue * Fix missing `BlockParamLiteral` type import issue

View File

@ -1,6 +1,6 @@
{ {
"name": "0x.js", "name": "0x.js",
"version": "1.0.1-rc.6", "version": "1.0.1",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -41,15 +41,16 @@
}, },
"license": "Apache-2.0", "license": "Apache-2.0",
"devDependencies": { "devDependencies": {
"@0xproject/abi-gen": "^1.0.7", "@0xproject/abi-gen": "^1.0.8",
"@0xproject/dev-utils": "^1.0.6", "@0xproject/dev-utils": "^1.0.7",
"@0xproject/migrations": "^1.0.6", "@0xproject/migrations": "^1.0.7",
"@0xproject/monorepo-scripts": "^1.0.7", "@0xproject/monorepo-scripts": "^1.0.8",
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42", "@types/mocha": "^2.2.42",
"@types/node": "^8.0.53", "@types/node": "^8.0.53",
"@types/sinon": "^2.2.2", "@types/sinon": "^2.2.2",
"@types/web3-provider-engine": "^14.0.0",
"awesome-typescript-loader": "^3.1.3", "awesome-typescript-loader": "^3.1.3",
"chai": "^4.0.1", "chai": "^4.0.1",
"chai-as-promised": "^7.1.0", "chai-as-promised": "^7.1.0",
@ -72,17 +73,17 @@
"webpack": "^3.1.0" "webpack": "^3.1.0"
}, },
"dependencies": { "dependencies": {
"@0xproject/assert": "^1.0.7", "@0xproject/assert": "^1.0.8",
"@0xproject/base-contract": "^2.0.1", "@0xproject/base-contract": "^2.0.2",
"@0xproject/contract-wrappers": "^1.0.1-rc.5", "@0xproject/contract-wrappers": "^1.0.1",
"@0xproject/order-utils": "^1.0.1-rc.6", "@0xproject/order-utils": "^1.0.1",
"@0xproject/order-watcher": "^1.0.1-rc.5", "@0xproject/order-watcher": "^1.0.1",
"@0xproject/subproviders": "^2.0.1", "@0xproject/subproviders": "^2.0.2",
"@0xproject/types": "^1.0.1-rc.6", "@0xproject/types": "^1.0.1",
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"@0xproject/web3-wrapper": "^2.0.1", "@0xproject/web3-wrapper": "^2.0.2",
"ethereum-types": "^1.0.5", "ethereum-types": "^1.0.6",
"ethers": "3.0.22", "ethers": "3.0.22",
"lodash": "^4.17.5", "lodash": "^4.17.5",
"web3-provider-engine": "14.0.6" "web3-provider-engine": "14.0.6"

View File

@ -46,6 +46,7 @@ export {
BalanceAndAllowance, BalanceAndAllowance,
OrderAndTraderInfo, OrderAndTraderInfo,
TraderInfo, TraderInfo,
ValidateOrderFillableOpts,
} from '@0xproject/contract-wrappers'; } from '@0xproject/contract-wrappers';
export { OrderWatcher, OnOrderStateChangeCallback, OrderWatcherConfig } from '@0xproject/order-watcher'; export { OrderWatcher, OnOrderStateChangeCallback, OrderWatcherConfig } from '@0xproject/order-watcher';

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "1.0.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1535377027, "timestamp": 1535377027,
"version": "1.0.7", "version": "1.0.7",

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.8 - _September 5, 2018_
* Dependencies updated
## v1.0.7 - _August 27, 2018_ ## v1.0.7 - _August 27, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,6 +1,6 @@
{ {
"name": "@0xproject/abi-gen", "name": "@0xproject/abi-gen",
"version": "1.0.7", "version": "1.0.8",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -30,10 +30,10 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
"dependencies": { "dependencies": {
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"chalk": "^2.3.0", "chalk": "^2.3.0",
"ethereum-types": "^1.0.5", "ethereum-types": "^1.0.6",
"glob": "^7.1.2", "glob": "^7.1.2",
"handlebars": "^4.0.11", "handlebars": "^4.0.11",
"lodash": "^4.17.5", "lodash": "^4.17.5",
@ -44,7 +44,7 @@
"yargs": "^10.0.3" "yargs": "^10.0.3"
}, },
"devDependencies": { "devDependencies": {
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/glob": "5.0.35", "@types/glob": "5.0.35",
"@types/handlebars": "^4.0.36", "@types/handlebars": "^4.0.36",
"@types/mkdirp": "^0.5.1", "@types/mkdirp": "^0.5.1",

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "1.0.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1535377027, "timestamp": 1535377027,
"version": "1.0.7", "version": "1.0.7",

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.8 - _September 5, 2018_
* Dependencies updated
## v1.0.7 - _August 27, 2018_ ## v1.0.7 - _August 27, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,6 +1,6 @@
{ {
"name": "@0xproject/assert", "name": "@0xproject/assert",
"version": "1.0.7", "version": "1.0.8",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -28,7 +28,7 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
"devDependencies": { "devDependencies": {
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42", "@types/mocha": "^2.2.42",
"@types/valid-url": "^1.0.2", "@types/valid-url": "^1.0.2",
@ -44,9 +44,9 @@
"typescript": "3.0.1" "typescript": "3.0.1"
}, },
"dependencies": { "dependencies": {
"@0xproject/json-schemas": "^1.0.1-rc.6", "@0xproject/json-schemas": "^1.0.1",
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"lodash": "^4.17.5", "lodash": "^4.17.5",
"valid-url": "^1.0.9" "valid-url": "^1.0.9"
}, },

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "2.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1535377027, "timestamp": 1535377027,
"version": "2.0.1", "version": "2.0.1",

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v2.0.2 - _September 5, 2018_
* Dependencies updated
## v2.0.1 - _August 27, 2018_ ## v2.0.1 - _August 27, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,6 +1,6 @@
{ {
"name": "@0xproject/base-contract", "name": "@0xproject/base-contract",
"version": "2.0.1", "version": "2.0.2",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -28,7 +28,7 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
"devDependencies": { "devDependencies": {
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"chai": "^4.0.1", "chai": "^4.0.1",
"copyfiles": "^2.0.0", "copyfiles": "^2.0.0",
@ -40,10 +40,10 @@
"typescript": "3.0.1" "typescript": "3.0.1"
}, },
"dependencies": { "dependencies": {
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"@0xproject/web3-wrapper": "^2.0.1", "@0xproject/web3-wrapper": "^2.0.2",
"ethereum-types": "^1.0.5", "ethereum-types": "^1.0.6",
"ethers": "3.0.22", "ethers": "3.0.22",
"lodash": "^4.17.5" "lodash": "^4.17.5"
}, },

View File

@ -1,4 +1,14 @@
[ [
{
"version": "2.0.0",
"changes": [
{
"note": "Change `OrderConfigRequest` to use BigNumber instead of string for relevant fields.",
"pr": 1058
}
],
"timestamp": 1536142250
},
{ {
"version": "2.0.0-rc.2", "version": "2.0.0-rc.2",
"changes": [ "changes": [

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v2.0.0 - _September 5, 2018_
* Change `OrderConfigRequest` to use BigNumber instead of string for relevant fields. (#1058)
## v2.0.0-rc.2 - _August 27, 2018_ ## v2.0.0-rc.2 - _August 27, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,6 +1,6 @@
{ {
"name": "@0xproject/connect", "name": "@0xproject/connect",
"version": "2.0.0-rc.2", "version": "2.0.0",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -43,11 +43,12 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
"dependencies": { "dependencies": {
"@0xproject/assert": "^1.0.7", "@0xproject/assert": "^1.0.8",
"@0xproject/json-schemas": "^1.0.1-rc.6", "@0xproject/json-schemas": "^1.0.1",
"@0xproject/types": "^1.0.1-rc.6", "@0xproject/order-utils": "^1.0.1",
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/types": "^1.0.1",
"@0xproject/utils": "^1.0.7", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.8",
"lodash": "^4.17.5", "lodash": "^4.17.5",
"query-string": "^5.0.1", "query-string": "^5.0.1",
"sinon": "^4.0.0", "sinon": "^4.0.0",
@ -55,7 +56,7 @@
"websocket": "^1.0.25" "websocket": "^1.0.25"
}, },
"devDependencies": { "devDependencies": {
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/fetch-mock": "^6.0.3", "@types/fetch-mock": "^6.0.3",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42", "@types/mocha": "^2.2.42",

View File

@ -151,7 +151,7 @@ export class HttpClient implements Client {
params: requestOpts, params: requestOpts,
payload: request, payload: request,
}; };
const responseJson = await this._requestAsync('/order_config', HttpRequestType.Post, httpRequestOpts); const responseJson = await this._requestAsync('/order_config', HttpRequestType.Get, httpRequestOpts);
const fees = relayerResponseJsonParsers.parseOrderConfigResponseJson(responseJson); const fees = relayerResponseJsonParsers.parseOrderConfigResponseJson(responseJson);
return fees; return fees;
} }

View File

@ -126,12 +126,12 @@ export interface PaginatedCollection<T> {
export interface OrderConfigRequest { export interface OrderConfigRequest {
makerAddress: string; makerAddress: string;
takerAddress: string; takerAddress: string;
makerAssetAmount: string; makerAssetAmount: BigNumber;
takerAssetAmount: string; takerAssetAmount: BigNumber;
makerAssetData: string; makerAssetData: string;
takerAssetData: string; takerAssetData: string;
exchangeAddress: string; exchangeAddress: string;
expirationTimeSeconds: string; expirationTimeSeconds: BigNumber;
} }
export interface OrderConfigResponse { export interface OrderConfigResponse {

View File

@ -1,5 +1,6 @@
import { assert } from '@0xproject/assert'; import { assert } from '@0xproject/assert';
import { schemas } from '@0xproject/json-schemas'; import { schemas } from '@0xproject/json-schemas';
import { orderParsingUtils } from '@0xproject/order-utils';
import { import {
APIOrder, APIOrder,
@ -19,7 +20,7 @@ export const relayerResponseJsonParsers = {
}, },
parseAssetPairsItemsJson(json: any): AssetPairsItem[] { parseAssetPairsItemsJson(json: any): AssetPairsItem[] {
return json.map((assetDataPair: any) => { return json.map((assetDataPair: any) => {
return typeConverters.convertStringsFieldsToBigNumbers(assetDataPair, [ return orderParsingUtils.convertStringsFieldsToBigNumbers(assetDataPair, [
'assetDataA.minAmount', 'assetDataA.minAmount',
'assetDataA.maxAmount', 'assetDataA.maxAmount',
'assetDataB.minAmount', 'assetDataB.minAmount',
@ -44,6 +45,6 @@ export const relayerResponseJsonParsers = {
}, },
parseOrderConfigResponseJson(json: any): OrderConfigResponse { parseOrderConfigResponseJson(json: any): OrderConfigResponse {
assert.doesConformToSchema('orderConfigResponse', json, schemas.relayerApiOrderConfigResponseSchema); assert.doesConformToSchema('orderConfigResponse', json, schemas.relayerApiOrderConfigResponseSchema);
return typeConverters.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']); return orderParsingUtils.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']);
}, },
}; };

View File

@ -1,4 +1,4 @@
import { BigNumber } from '@0xproject/utils'; import { orderParsingUtils } from '@0xproject/order-utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { APIOrder } from '../types'; import { APIOrder } from '../types';
@ -21,28 +21,6 @@ export const typeConverters = {
}; };
}, },
convertAPIOrderStringFieldsToBigNumber(apiOrder: any): APIOrder { convertAPIOrderStringFieldsToBigNumber(apiOrder: any): APIOrder {
return { ...apiOrder, order: typeConverters.convertOrderStringFieldsToBigNumber(apiOrder.order) }; return { ...apiOrder, order: orderParsingUtils.convertOrderStringFieldsToBigNumber(apiOrder.order) };
},
convertOrderStringFieldsToBigNumber(order: any): any {
return typeConverters.convertStringsFieldsToBigNumbers(order, [
'makerAssetAmount',
'takerAssetAmount',
'makerFee',
'takerFee',
'expirationTimeSeconds',
'salt',
]);
},
convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
const result = _.assign({}, obj);
_.each(fields, field => {
_.update(result, field, (value: string) => {
if (_.isUndefined(value)) {
throw new Error(`Could not find field '${field}' while converting string fields to BigNumber.`);
}
return new BigNumber(value);
});
});
return result;
}, },
}; };

View File

@ -1,3 +1,4 @@
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai'; import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised'; import * as chaiAsPromised from 'chai-as-promised';
import * as dirtyChai from 'dirty-chai'; import * as dirtyChai from 'dirty-chai';
@ -138,21 +139,21 @@ describe('HttpClient', () => {
const request = { const request = {
makerAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b', makerAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
takerAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32', takerAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
makerAssetAmount: '10000000000000000', makerAssetAmount: new BigNumber('10000000000000000'),
takerAssetAmount: '20000000000000000', takerAssetAmount: new BigNumber('20000000000000000'),
expirationTimeSeconds: '1532560590', expirationTimeSeconds: new BigNumber('1532560590'),
makerAssetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d', makerAssetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
takerAssetData: '0x0257179264389b814a946f3e92105513705ca6b990', takerAssetData: '0x0257179264389b814a946f3e92105513705ca6b990',
exchangeAddress: '0x12459c951127e0c374ff9105dda097662a027093', exchangeAddress: '0x12459c951127e0c374ff9105dda097662a027093',
}; };
const url = `${relayUrl}/order_config`; const url = `${relayUrl}/order_config`;
it('gets order config', async () => { it('gets order config', async () => {
fetchMock.post(url, orderConfigResponseJSON); fetchMock.get(url, orderConfigResponseJSON);
const fees = await relayerClient.getOrderConfigAsync(request); const fees = await relayerClient.getOrderConfigAsync(request);
expect(fees).to.be.deep.equal(orderConfigResponse); expect(fees).to.be.deep.equal(orderConfigResponse);
}); });
it('does not mutate input', async () => { it('does not mutate input', async () => {
fetchMock.post(url, orderConfigResponseJSON); fetchMock.get(url, orderConfigResponseJSON);
const makerAssetAmountBefore = request.makerAssetAmount; const makerAssetAmountBefore = request.makerAssetAmount;
const takerAssetAmountBefore = request.takerAssetAmount; const takerAssetAmountBefore = request.takerAssetAmount;
const expirationTimeSecondsBefore = request.expirationTimeSeconds; const expirationTimeSecondsBefore = request.expirationTimeSeconds;
@ -162,7 +163,7 @@ describe('HttpClient', () => {
expect(expirationTimeSecondsBefore).to.be.deep.equal(request.expirationTimeSeconds); expect(expirationTimeSecondsBefore).to.be.deep.equal(request.expirationTimeSeconds);
}); });
it('throws an error for invalid JSON response', async () => { it('throws an error for invalid JSON response', async () => {
fetchMock.post(url, { test: 'dummy' }); fetchMock.get(url, { test: 'dummy' });
expect(relayerClient.getOrderConfigAsync(request)).to.be.rejected(); expect(relayerClient.getOrderConfigAsync(request)).to.be.rejected();
}); });
}); });

View File

@ -1,11 +1,27 @@
[ [
{ {
"version": "1.0.1-rc.6", "version": "1.0.1",
"changes": [ "changes": [
{ {
"note": "Add `OrderValidatorWrapper`" "note": "Add `OrderValidatorWrapper`"
},
{
"note":
"Fix bug where contracts not deployed on a network showed an `EXCHANGE_CONTRACT_DOES_NOT_EXIST` error instead of `CONTRACT_NOT_DEPLOYED_ON_NETWORK`",
"pr": 1044
},
{
"note":
"Export `AssetBalanceAndProxyAllowanceFetcher` and `OrderFilledCancelledFetcher` implementations",
"pr": 1054
},
{
"note":
"Add `validateOrderFillableOrThrowAsync` and `validateFillOrderThrowIfInvalidAsync` to ExchangeWrapper",
"pr": 1054
} }
] ],
"timestamp": 1536142250
}, },
{ {
"version": "1.0.1-rc.5", "version": "1.0.1-rc.5",

View File

@ -5,6 +5,13 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.1 - _September 5, 2018_
* Add `OrderValidatorWrapper`
* Fix bug where contracts not deployed on a network showed an `EXCHANGE_CONTRACT_DOES_NOT_EXIST` error instead of `CONTRACT_NOT_DEPLOYED_ON_NETWORK` (#1044)
* Export `AssetBalanceAndProxyAllowanceFetcher` and `OrderFilledCancelledFetcher` implementations (#1054)
* Add `validateOrderFillableOrThrowAsync` and `validateFillOrderThrowIfInvalidAsync` to ExchangeWrapper (#1054)
## v1.0.1-rc.5 - _August 27, 2018_ ## v1.0.1-rc.5 - _August 27, 2018_
* Fix missing `BlockParamLiteral` type import issue * Fix missing `BlockParamLiteral` type import issue

View File

@ -1,6 +1,6 @@
{ {
"name": "@0xproject/contract-wrappers", "name": "@0xproject/contract-wrappers",
"version": "1.0.1-rc.5", "version": "1.0.1",
"description": "Smart TS wrappers for 0x smart contracts", "description": "Smart TS wrappers for 0x smart contracts",
"keywords": [ "keywords": [
"0xproject", "0xproject",
@ -12,7 +12,7 @@
"types": "lib/src/index.d.ts", "types": "lib/src/index.d.ts",
"scripts": { "scripts": {
"build": "yarn pre_build && tsc -b", "build": "yarn pre_build && tsc -b",
"pre_build": "run-s update_artifacts_v2_beta update_artifacts_v2 generate_contract_wrappers copy_artifacts", "pre_build": "run-s update_artifacts generate_contract_wrappers copy_artifacts",
"generate_contract_wrappers": "abi-gen --abis 'src/artifacts/@(Exchange|DummyERC20Token|DummyERC721Token|ZRXToken|ERC20Token|ERC721Token|WETH9|ERC20Proxy|ERC721Proxy|Forwarder|OrderValidator).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers", "generate_contract_wrappers": "abi-gen --abis 'src/artifacts/@(Exchange|DummyERC20Token|DummyERC721Token|ZRXToken|ERC20Token|ERC721Token|WETH9|ERC20Proxy|ERC721Proxy|Forwarder|OrderValidator).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers",
"lint": "tslint --project . --exclude **/src/contract_wrappers/**/* --exclude **/lib/**/*", "lint": "tslint --project . --exclude **/src/contract_wrappers/**/* --exclude **/lib/**/*",
"test:circleci": "run-s test:coverage", "test:circleci": "run-s test:coverage",
@ -20,16 +20,14 @@
"rebuild_and_test": "run-s build test", "rebuild_and_test": "run-s build test",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"update_artifacts_v2_beta": "for i in ${npm_package_config_contracts_v2_beta}; do copyfiles -u 4 ../migrations/artifacts/2.0.0-beta-testnet/$i.json src/artifacts; done;", "update_artifacts": "for i in ${npm_package_config_contracts_v2}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json src/artifacts; done;",
"update_artifacts_v2": "for i in ${npm_package_config_contracts_v2}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json src/artifacts; done;",
"copy_artifacts": "copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts", "copy_artifacts": "copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts",
"clean": "shx rm -rf _bundles lib test_temp test/artifacts src/contract_wrappers/generated src/artifacts generated_docs", "clean": "shx rm -rf _bundles lib test_temp test/artifacts src/contract_wrappers/generated src/artifacts generated_docs",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit", "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
}, },
"config": { "config": {
"contracts_v2_beta": "AssetProxyOwner Exchange ERC20Proxy ERC20Token ERC721Proxy ERC721Token WETH9 ZRXToken Forwarder OrderValidator", "contracts_v2": "AssetProxyOwner Exchange ERC20Proxy ERC20Token ERC721Proxy ERC721Token WETH9 ZRXToken Forwarder OrderValidator DummyERC20Token DummyERC721Token",
"contracts_v2": "DummyERC20Token DummyERC721Token",
"postpublish": { "postpublish": {
"assets": [] "assets": []
} }
@ -43,16 +41,17 @@
"node": ">=6.0.0" "node": ">=6.0.0"
}, },
"devDependencies": { "devDependencies": {
"@0xproject/abi-gen": "^1.0.7", "@0xproject/abi-gen": "^1.0.8",
"@0xproject/dev-utils": "^1.0.6", "@0xproject/dev-utils": "^1.0.7",
"@0xproject/migrations": "^1.0.6", "@0xproject/migrations": "^1.0.7",
"@0xproject/subproviders": "^2.0.1", "@0xproject/subproviders": "^2.0.2",
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42", "@types/mocha": "^2.2.42",
"@types/node": "^8.0.53", "@types/node": "^8.0.53",
"@types/sinon": "^2.2.2", "@types/sinon": "^2.2.2",
"@types/uuid": "^3.4.2", "@types/uuid": "^3.4.2",
"@types/web3-provider-engine": "^14.0.0",
"awesome-typescript-loader": "^3.1.3", "awesome-typescript-loader": "^3.1.3",
"chai": "^4.0.1", "chai": "^4.0.1",
"chai-as-promised": "^7.1.0", "chai-as-promised": "^7.1.0",
@ -73,16 +72,16 @@
"web3-provider-engine": "14.0.6" "web3-provider-engine": "14.0.6"
}, },
"dependencies": { "dependencies": {
"@0xproject/assert": "^1.0.7", "@0xproject/assert": "^1.0.8",
"@0xproject/base-contract": "^2.0.1", "@0xproject/base-contract": "^2.0.2",
"@0xproject/fill-scenarios": "^1.0.1-rc.5", "@0xproject/fill-scenarios": "^1.0.1",
"@0xproject/json-schemas": "^1.0.1-rc.6", "@0xproject/json-schemas": "^1.0.1",
"@0xproject/order-utils": "^1.0.1-rc.6", "@0xproject/order-utils": "^1.0.1",
"@0xproject/types": "^1.0.1-rc.6", "@0xproject/types": "^1.0.1",
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"@0xproject/web3-wrapper": "^2.0.1", "@0xproject/web3-wrapper": "^2.0.2",
"ethereum-types": "^1.0.5", "ethereum-types": "^1.0.6",
"ethereumjs-blockstream": "5.0.0", "ethereumjs-blockstream": "5.0.0",
"ethereumjs-util": "^5.1.1", "ethereumjs-util": "^5.1.1",
"ethers": "3.0.22", "ethers": "3.0.22",

View File

@ -111,6 +111,8 @@ export class ContractWrappers {
this.exchange = new ExchangeWrapper( this.exchange = new ExchangeWrapper(
this._web3Wrapper, this._web3Wrapper,
config.networkId, config.networkId,
this.erc20Token,
this.erc721Token,
config.exchangeContractAddress, config.exchangeContractAddress,
config.zrxContractAddress, config.zrxContractAddress,
blockPollingIntervalMs, blockPollingIntervalMs,

View File

@ -145,9 +145,12 @@ export abstract class ContractWrapper {
} }
protected _getContractAddress(artifact: ContractArtifact, addressIfExists?: string): string { protected _getContractAddress(artifact: ContractArtifact, addressIfExists?: string): string {
if (_.isUndefined(addressIfExists)) { if (_.isUndefined(addressIfExists)) {
if (_.isUndefined(artifact.networks[this._networkId])) {
throw new Error(ContractWrappersError.ContractNotDeployedOnNetwork);
}
const contractAddress = artifact.networks[this._networkId].address; const contractAddress = artifact.networks[this._networkId].address;
if (_.isUndefined(contractAddress)) { if (_.isUndefined(contractAddress)) {
throw new Error(ContractWrappersError.ExchangeContractDoesNotExist); throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contractName]);
} }
return contractAddress; return contractAddress;
} else { } else {

View File

@ -1,12 +1,19 @@
import { schemas } from '@0xproject/json-schemas'; import { schemas } from '@0xproject/json-schemas';
import { assetDataUtils } from '@0xproject/order-utils'; import {
assetDataUtils,
BalanceAndProxyAllowanceLazyStore,
ExchangeTransferSimulator,
OrderValidationUtils,
} from '@0xproject/order-utils';
import { AssetProxyId, Order, SignedOrder } from '@0xproject/types'; import { AssetProxyId, Order, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils'; import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; import { BlockParamLiteral, ContractAbi, LogWithDecodedArgs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { artifacts } from '../artifacts'; import { artifacts } from '../artifacts';
import { AssetBalanceAndProxyAllowanceFetcher } from '../fetchers/asset_balance_and_proxy_allowance_fetcher';
import { OrderFilledCancelledFetcher } from '../fetchers/order_filled_cancelled_fetcher';
import { methodOptsSchema } from '../schemas/method_opts_schema'; import { methodOptsSchema } from '../schemas/method_opts_schema';
import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema'; import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema';
import { txOptsSchema } from '../schemas/tx_opts_schema'; import { txOptsSchema } from '../schemas/tx_opts_schema';
@ -17,13 +24,17 @@ import {
IndexedFilterValues, IndexedFilterValues,
MethodOpts, MethodOpts,
OrderInfo, OrderInfo,
OrderStatus,
OrderTransactionOpts, OrderTransactionOpts,
ValidateOrderFillableOpts,
} from '../types'; } from '../types';
import { assert } from '../utils/assert'; import { assert } from '../utils/assert';
import { decorators } from '../utils/decorators'; import { decorators } from '../utils/decorators';
import { TransactionEncoder } from '../utils/transaction_encoder'; import { TransactionEncoder } from '../utils/transaction_encoder';
import { ContractWrapper } from './contract_wrapper'; import { ContractWrapper } from './contract_wrapper';
import { ERC20TokenWrapper } from './erc20_token_wrapper';
import { ERC721TokenWrapper } from './erc721_token_wrapper';
import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from './generated/exchange'; import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from './generated/exchange';
/** /**
@ -33,6 +44,8 @@ import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from './generated
export class ExchangeWrapper extends ContractWrapper { export class ExchangeWrapper extends ContractWrapper {
public abi: ContractAbi = artifacts.Exchange.compilerOutput.abi; public abi: ContractAbi = artifacts.Exchange.compilerOutput.abi;
private _exchangeContractIfExists?: ExchangeContract; private _exchangeContractIfExists?: ExchangeContract;
private _erc721TokenWrapper: ERC721TokenWrapper;
private _erc20TokenWrapper: ERC20TokenWrapper;
private _contractAddressIfExists?: string; private _contractAddressIfExists?: string;
private _zrxContractAddressIfExists?: string; private _zrxContractAddressIfExists?: string;
/** /**
@ -48,11 +61,15 @@ export class ExchangeWrapper extends ContractWrapper {
constructor( constructor(
web3Wrapper: Web3Wrapper, web3Wrapper: Web3Wrapper,
networkId: number, networkId: number,
erc20TokenWrapper: ERC20TokenWrapper,
erc721TokenWrapper: ERC721TokenWrapper,
contractAddressIfExists?: string, contractAddressIfExists?: string,
zrxContractAddressIfExists?: string, zrxContractAddressIfExists?: string,
blockPollingIntervalMs?: number, blockPollingIntervalMs?: number,
) { ) {
super(web3Wrapper, networkId, blockPollingIntervalMs); super(web3Wrapper, networkId, blockPollingIntervalMs);
this._erc20TokenWrapper = erc20TokenWrapper;
this._erc721TokenWrapper = erc721TokenWrapper;
this._contractAddressIfExists = contractAddressIfExists; this._contractAddressIfExists = contractAddressIfExists;
this._zrxContractAddressIfExists = zrxContractAddressIfExists; this._zrxContractAddressIfExists = zrxContractAddressIfExists;
} }
@ -1084,6 +1101,64 @@ export class ExchangeWrapper extends ContractWrapper {
); );
return logs; return logs;
} }
/**
* Validate if the supplied order is fillable, and throw if it isn't
* @param signedOrder SignedOrder of interest
* @param opts ValidateOrderFillableOpts options (e.g expectedFillTakerTokenAmount.
* If it isn't supplied, we check if the order is fillable for a non-zero amount)
*/
public async validateOrderFillableOrThrowAsync(
signedOrder: SignedOrder,
opts: ValidateOrderFillableOpts = {},
): Promise<void> {
const balanceAllowanceFetcher = new AssetBalanceAndProxyAllowanceFetcher(
this._erc20TokenWrapper,
this._erc721TokenWrapper,
BlockParamLiteral.Latest,
);
const balanceAllowanceStore = new BalanceAndProxyAllowanceLazyStore(balanceAllowanceFetcher);
const exchangeTradeSimulator = new ExchangeTransferSimulator(balanceAllowanceStore);
const expectedFillTakerTokenAmountIfExists = opts.expectedFillTakerTokenAmount;
const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest);
const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher);
await orderValidationUtils.validateOrderFillableOrThrowAsync(
exchangeTradeSimulator,
signedOrder,
this.getZRXAssetData(),
expectedFillTakerTokenAmountIfExists,
);
}
/**
* Validate a call to FillOrder and throw if it wouldn't succeed
* @param signedOrder SignedOrder of interest
* @param fillTakerAssetAmount Amount we'd like to fill the order for
* @param takerAddress The taker of the order
*/
public async validateFillOrderThrowIfInvalidAsync(
signedOrder: SignedOrder,
fillTakerAssetAmount: BigNumber,
takerAddress: string,
): Promise<void> {
const balanceAllowanceFetcher = new AssetBalanceAndProxyAllowanceFetcher(
this._erc20TokenWrapper,
this._erc721TokenWrapper,
BlockParamLiteral.Latest,
);
const balanceAllowanceStore = new BalanceAndProxyAllowanceLazyStore(balanceAllowanceFetcher);
const exchangeTradeSimulator = new ExchangeTransferSimulator(balanceAllowanceStore);
const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest);
const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher);
await orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
exchangeTradeSimulator,
this._web3Wrapper.getProvider(),
signedOrder,
fillTakerAssetAmount,
takerAddress,
this.getZRXAssetData(),
);
}
/** /**
* Retrieves the Ethereum address of the Exchange contract deployed on the network * Retrieves the Ethereum address of the Exchange contract deployed on the network
* that the user-passed web3 provider is connected to. * that the user-passed web3 provider is connected to.

View File

@ -1,8 +1,11 @@
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
import { BlockParamLiteral, ERC20TokenWrapper, ERC721TokenWrapper } from '@0xproject/contract-wrappers';
import { AbstractBalanceAndProxyAllowanceFetcher, assetDataUtils } from '@0xproject/order-utils'; import { AbstractBalanceAndProxyAllowanceFetcher, assetDataUtils } from '@0xproject/order-utils';
import { AssetProxyId, ERC20AssetData, ERC721AssetData } from '@0xproject/types'; import { AssetProxyId, ERC20AssetData, ERC721AssetData } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils'; import { BigNumber } from '@0xproject/utils';
import { BlockParamLiteral } from 'ethereum-types';
import { ERC20TokenWrapper } from '../contract_wrappers/erc20_token_wrapper';
import { ERC721TokenWrapper } from '../contract_wrappers/erc721_token_wrapper';
export class AssetBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher { export class AssetBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher {
private readonly _erc20Token: ERC20TokenWrapper; private readonly _erc20Token: ERC20TokenWrapper;

View File

@ -1,7 +1,10 @@
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
import { BlockParamLiteral, ExchangeWrapper } from '@0xproject/contract-wrappers';
import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils'; import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils';
import { BigNumber } from '@0xproject/utils'; import { BigNumber } from '@0xproject/utils';
import { BlockParamLiteral } from 'ethereum-types';
import { ERC20TokenWrapper } from '../contract_wrappers/erc20_token_wrapper';
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
export class OrderFilledCancelledFetcher implements AbstractOrderFilledCancelledFetcher { export class OrderFilledCancelledFetcher implements AbstractOrderFilledCancelledFetcher {
private readonly _exchange: ExchangeWrapper; private readonly _exchange: ExchangeWrapper;

View File

@ -25,6 +25,7 @@ export {
BalanceAndAllowance, BalanceAndAllowance,
OrderAndTraderInfo, OrderAndTraderInfo,
TraderInfo, TraderInfo,
ValidateOrderFillableOpts,
} from './types'; } from './types';
export { Order, SignedOrder, AssetProxyId } from '@0xproject/types'; export { Order, SignedOrder, AssetProxyId } from '@0xproject/types';
@ -85,3 +86,8 @@ export {
ExchangeEventArgs, ExchangeEventArgs,
ExchangeEvents, ExchangeEvents,
} from './contract_wrappers/generated/exchange'; } from './contract_wrappers/generated/exchange';
export { AbstractBalanceAndProxyAllowanceFetcher, AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils';
export { AssetBalanceAndProxyAllowanceFetcher } from './fetchers/asset_balance_and_proxy_allowance_fetcher';
export { OrderFilledCancelledFetcher } from './fetchers/order_filled_cancelled_fetcher';

View File

@ -358,7 +358,7 @@ describe('ExchangeWrapper', () => {
describe('#getVersionAsync', () => { describe('#getVersionAsync', () => {
it('should return version the hash', async () => { it('should return version the hash', async () => {
const version = await contractWrappers.exchange.getVersionAsync(); const version = await contractWrappers.exchange.getVersionAsync();
const VERSION = '2.0.1-alpha'; const VERSION = '2.0.0';
expect(version).to.be.equal(VERSION); expect(version).to.be.equal(VERSION);
}); });
}); });

View File

@ -1,14 +1,35 @@
## Contracts ## Contracts
Smart contracts that implement the 0x protocol. Smart contracts that implement the 0x protocol. Addresses of the deployed contracts can be found [here](https://0xproject.com/wiki#Deployed-Addresses).
## Usage ## Usage
* [Docs](https://0xproject.com/docs/contracts) ### 2.0.0
* [Overview of 0x protocol architecture](https://0xproject.com/wiki#Architecture)
* [0x smart contract interactions](https://0xproject.com/wiki#Contract-Interactions) Contracts that make up and interact with version 2.0.0 of the protocol can be found in the `src/2.0.0` directory. The contents of this directory are broken down into the following subdirectories:
* [Deployed smart contract addresses](https://0xproject.com/wiki#Deployed-Addresses)
* [0x protocol message format](https://0xproject.com/wiki#Message-Format) * protocol
* This directory contains the contracts that make up version 2.0.0. A full specification can be found [here](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
* extensions
* This directory contains contracts that interact with the 2.0.0 contracts and will be used in production, such as the [Forwarder](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/forwarder-specification.md) contract.
* examples
* This directory contains example implementations of contracts that interact with the protocol but are _not_ intended for use in production. Examples include [filter](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#filter-contracts) contracts, a [Wallet](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#wallet) contract, and a [Validator](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#validator) contract, among others.
* tokens
* This directory contains implementations of different tokens and token standards, including [wETH](https://weth.io/), ZRX, [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md), and [ERC721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md).
* multisig
* This directory contains the [Gnosis MultiSigWallet](https://github.com/gnosis/MultiSigWallet) and a custom extension that adds a timelock to transactions within the MultiSigWallet.
* utils
* This directory contains libraries and utils that are shared across all of the other directories.
* test
* This directory contains mocks and other contracts that are used solely for testing contracts within the other directories.
### 1.0.0
Contracts that make up version 1.0.0 of the protocol can be found in `src/1.0.0`. These contracts are considered deprecated and will have limited support going forward.
## Bug bounty
A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0xproject.com/wiki#Bug-Bounty).
## Contributing ## Contributing

View File

@ -1,5 +1,5 @@
{ {
"artifactsDir": "../migrations/artifacts/2.0.0", "artifactsDir": "../migrations/artifacts/development",
"contractsDir": "src/", "contractsDir": "src/",
"compilerSettings": { "compilerSettings": {
"optimizer": { "optimizer": {

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "contracts", "name": "contracts",
"version": "2.1.42", "version": "2.1.43",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -13,20 +13,17 @@
"scripts": { "scripts": {
"build": "yarn pre_build && tsc -b", "build": "yarn pre_build && tsc -b",
"pre_build": "run-s compile copy_artifacts generate_contract_wrappers", "pre_build": "run-s compile copy_artifacts generate_contract_wrappers",
"copy_artifacts": "copyfiles -u 4 '../migrations/artifacts/2.0.0/**/*' ./lib/artifacts;", "copy_artifacts": "copyfiles -u 4 '../migrations/artifacts/development/**/*' ./lib/artifacts;",
"test": "yarn run_mocha", "test": "yarn run_mocha",
"rebuild_and_test": "run-s build test", "rebuild_and_test": "run-s build test",
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html", "test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha", "test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
"run_mocha": "run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile": "sol-compiler --contracts-dir src", "compile": "sol-compiler --contracts-dir src",
"clean": "shx rm -rf lib generated_contract_wrappers", "clean": "shx rm -rf lib generated_contract_wrappers",
"generate_contract_wrappers": "generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output generated_contract_wrappers --backend ethers",
"abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output generated_contract_wrappers --backend ethers", "lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/* --exclude **/lib/**/* && yarn lint-contracts",
"lint":
"tslint --project . --exclude **/src/generated_contract_wrappers/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text", "coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html", "coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html", "profiler:report:html": "istanbul report html && open coverage/index.html",
@ -35,8 +32,7 @@
"lint-contracts": "solhint src/2.0.0/**/**/**/**/*.sol" "lint-contracts": "solhint src/2.0.0/**/**/**/**/*.sol"
}, },
"config": { "config": {
"abis": "abis": "../migrations/artifacts/development/@(AssetProxyOwner|DummyERC20Token|DummyERC721Receiver|DummyERC721Token|DummyMultipleReturnERC20Token|DummyNoReturnERC20Token|ERC20Proxy|ERC721Proxy|Forwarder|Exchange|ExchangeWrapper|IAssetData|IAssetProxy|InvalidERC721Receiver|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|OrderValidator|ReentrantERC20Token|TestAssetProxyOwner|TestAssetProxyDispatcher|TestConstants|TestExchangeInternals|TestLibBytes|TestLibs|TestSignatureValidator|TestStaticCallReceiver|Validator|Wallet|TokenRegistry|Whitelist|WETH9|ZRXToken).json"
"../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Receiver|DummyERC721Token|DummyMultipleReturnERC20Token|DummyNoReturnERC20Token|ERC20Proxy|ERC721Proxy|Forwarder|Exchange|ExchangeWrapper|IAssetData|IAssetProxy|InvalidERC721Receiver|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|OrderValidator|ReentrantERC20Token|TestAssetProxyOwner|TestAssetProxyDispatcher|TestConstants|TestExchangeInternals|TestLibBytes|TestLibs|TestSignatureValidator|TestStaticCallReceiver|Validator|Wallet|TokenRegistry|Whitelist|WETH9|ZRXToken).json"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -49,12 +45,12 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md",
"devDependencies": { "devDependencies": {
"@0xproject/abi-gen": "^1.0.7", "@0xproject/abi-gen": "^1.0.8",
"@0xproject/dev-utils": "^1.0.6", "@0xproject/dev-utils": "^1.0.7",
"@0xproject/sol-compiler": "^1.1.1", "@0xproject/sol-compiler": "^1.1.2",
"@0xproject/sol-cov": "^2.1.1", "@0xproject/sol-cov": "^2.1.2",
"@0xproject/subproviders": "^2.0.1", "@0xproject/subproviders": "^2.0.2",
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/bn.js": "^4.11.0", "@types/bn.js": "^4.11.0",
"@types/ethereumjs-abi": "^0.6.0", "@types/ethereumjs-abi": "^0.6.0",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
@ -76,15 +72,15 @@
"yargs": "^10.0.3" "yargs": "^10.0.3"
}, },
"dependencies": { "dependencies": {
"@0xproject/base-contract": "^2.0.1", "@0xproject/base-contract": "^2.0.2",
"@0xproject/order-utils": "^1.0.1-rc.6", "@0xproject/order-utils": "^1.0.1",
"@0xproject/types": "^1.0.1-rc.6", "@0xproject/types": "^1.0.1",
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"@0xproject/web3-wrapper": "^2.0.1", "@0xproject/web3-wrapper": "^2.0.2",
"@types/js-combinatorics": "^0.5.29", "@types/js-combinatorics": "^0.5.29",
"bn.js": "^4.11.8", "bn.js": "^4.11.8",
"ethereum-types": "^1.0.5", "ethereum-types": "^1.0.6",
"ethereumjs-abi": "0.6.5", "ethereumjs-abi": "0.6.5",
"ethereumjs-util": "^5.1.1", "ethereumjs-util": "^5.1.1",
"ethers": "3.0.22", "ethers": "3.0.22",

View File

@ -34,7 +34,6 @@ contract Forwarder is
MixinExchangeWrapper, MixinExchangeWrapper,
MixinForwarderCore MixinForwarderCore
{ {
constructor ( constructor (
address _exchange, address _exchange,
bytes memory _zrxAssetData, bytes memory _zrxAssetData,

View File

@ -31,7 +31,6 @@ contract MixinAssets is
LibConstants, LibConstants,
MAssets MAssets
{ {
using LibBytes for bytes; using LibBytes for bytes;
bytes4 constant internal ERC20_TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)")); bytes4 constant internal ERC20_TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)"));

View File

@ -34,7 +34,6 @@ contract MixinExchangeWrapper is
LibConstants, LibConstants,
MExchangeWrapper MExchangeWrapper
{ {
/// @dev Fills the input order. /// @dev Fills the input order.
/// Returns false if the transaction would otherwise revert. /// Returns false if the transaction would otherwise revert.
/// @param order Order struct containing order specifications. /// @param order Order struct containing order specifications.
@ -61,7 +60,7 @@ contract MixinExchangeWrapper is
// Call `fillOrder` and handle any exceptions gracefully // Call `fillOrder` and handle any exceptions gracefully
assembly { assembly {
let success := call( let success := call(
gas, // forward all gas, TODO: look into gas consumption of assert/throw gas, // forward all gas
exchange, // call address of Exchange contract exchange, // call address of Exchange contract
0, // transfer 0 wei 0, // transfer 0 wei
add(fillOrderCalldata, 32), // pointer to start of input (skip array length in first 32 bytes) add(fillOrderCalldata, 32), // pointer to start of input (skip array length in first 32 bytes)

View File

@ -39,7 +39,6 @@ contract MixinForwarderCore is
MExchangeWrapper, MExchangeWrapper,
IForwarderCore IForwarderCore
{ {
using LibBytes for bytes; using LibBytes for bytes;
/// @dev Constructor approves ERC20 proxy to transfer ZRX and WETH on this contract's behalf. /// @dev Constructor approves ERC20 proxy to transfer ZRX and WETH on this contract's behalf.
@ -47,11 +46,13 @@ contract MixinForwarderCore is
public public
{ {
address proxyAddress = EXCHANGE.getAssetProxy(ERC20_DATA_ID); address proxyAddress = EXCHANGE.getAssetProxy(ERC20_DATA_ID);
if (proxyAddress != address(0)) { require(
proxyAddress != address(0),
"UNREGISTERED_ASSET_PROXY"
);
ETHER_TOKEN.approve(proxyAddress, MAX_UINT); ETHER_TOKEN.approve(proxyAddress, MAX_UINT);
ZRX_TOKEN.approve(proxyAddress, MAX_UINT); ZRX_TOKEN.approve(proxyAddress, MAX_UINT);
} }
}
/// @dev Purchases as much of orders' makerAssets as possible by selling up to 95% of transaction's ETH value. /// @dev Purchases as much of orders' makerAssets as possible by selling up to 95% of transaction's ETH value.
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract. /// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.

View File

@ -28,7 +28,6 @@ contract MixinWeth is
LibConstants, LibConstants,
MWeth MWeth
{ {
/// @dev Default payabale function, this allows us to withdraw WETH /// @dev Default payabale function, this allows us to withdraw WETH
function () function ()
public public

View File

@ -24,7 +24,6 @@ import "../interfaces/IAssets.sol";
contract MAssets is contract MAssets is
IAssets IAssets
{ {
/// @dev Transfers given amount of asset to sender. /// @dev Transfers given amount of asset to sender.
/// @param assetData Byte array encoded for the respective asset proxy. /// @param assetData Byte array encoded for the respective asset proxy.
/// @param amount Amount of asset to transfer to sender. /// @param amount Amount of asset to transfer to sender.

View File

@ -28,11 +28,11 @@ import "../../utils/LibBytes/LibBytes.sol";
contract OrderValidator { contract OrderValidator {
using LibBytes for bytes;
bytes4 constant internal ERC20_DATA_ID = bytes4(keccak256("ERC20Token(address)")); bytes4 constant internal ERC20_DATA_ID = bytes4(keccak256("ERC20Token(address)"));
bytes4 constant internal ERC721_DATA_ID = bytes4(keccak256("ERC721Token(address,uint256)")); bytes4 constant internal ERC721_DATA_ID = bytes4(keccak256("ERC721Token(address,uint256)"));
using LibBytes for bytes;
struct TraderInfo { struct TraderInfo {
uint256 makerBalance; // Maker's balance of makerAsset uint256 makerBalance; // Maker's balance of makerAsset
uint256 makerAllowance; // Maker's allowance to corresponding AssetProxy uint256 makerAllowance; // Maker's allowance to corresponding AssetProxy

View File

@ -1,13 +1,14 @@
// solhint-disable // solhint-disable
pragma solidity ^0.4.10; pragma solidity ^0.4.15;
/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution. /// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.
/// @author Stefan George - <stefan.george@consensys.net> /// @author Stefan George - <stefan.george@consensys.net>
contract MultiSigWallet { contract MultiSigWallet {
uint constant public MAX_OWNER_COUNT = 50; /*
* Events
*/
event Confirmation(address indexed sender, uint indexed transactionId); event Confirmation(address indexed sender, uint indexed transactionId);
event Revocation(address indexed sender, uint indexed transactionId); event Revocation(address indexed sender, uint indexed transactionId);
event Submission(uint indexed transactionId); event Submission(uint indexed transactionId);
@ -18,6 +19,14 @@ contract MultiSigWallet {
event OwnerRemoval(address indexed owner); event OwnerRemoval(address indexed owner);
event RequirementChange(uint required); event RequirementChange(uint required);
/*
* Constants
*/
uint constant public MAX_OWNER_COUNT = 50;
/*
* Storage
*/
mapping (uint => Transaction) public transactions; mapping (uint => Transaction) public transactions;
mapping (uint => mapping (address => bool)) public confirmations; mapping (uint => mapping (address => bool)) public confirmations;
mapping (address => bool) public isOwner; mapping (address => bool) public isOwner;
@ -32,60 +41,54 @@ contract MultiSigWallet {
bool executed; bool executed;
} }
/*
* Modifiers
*/
modifier onlyWallet() { modifier onlyWallet() {
if (msg.sender != address(this)) require(msg.sender == address(this));
throw;
_; _;
} }
modifier ownerDoesNotExist(address owner) { modifier ownerDoesNotExist(address owner) {
if (isOwner[owner]) require(!isOwner[owner]);
throw;
_; _;
} }
modifier ownerExists(address owner) { modifier ownerExists(address owner) {
if (!isOwner[owner]) require(isOwner[owner]);
throw;
_; _;
} }
modifier transactionExists(uint transactionId) { modifier transactionExists(uint transactionId) {
if (transactions[transactionId].destination == 0) require(transactions[transactionId].destination != 0);
throw;
_; _;
} }
modifier confirmed(uint transactionId, address owner) { modifier confirmed(uint transactionId, address owner) {
if (!confirmations[transactionId][owner]) require(confirmations[transactionId][owner]);
throw;
_; _;
} }
modifier notConfirmed(uint transactionId, address owner) { modifier notConfirmed(uint transactionId, address owner) {
if (confirmations[transactionId][owner]) require(!confirmations[transactionId][owner]);
throw;
_; _;
} }
modifier notExecuted(uint transactionId) { modifier notExecuted(uint transactionId) {
if (transactions[transactionId].executed) require(!transactions[transactionId].executed);
throw;
_; _;
} }
modifier notNull(address _address) { modifier notNull(address _address) {
if (_address == 0) require(_address != 0);
throw;
_; _;
} }
modifier validRequirement(uint ownerCount, uint _required) { modifier validRequirement(uint ownerCount, uint _required) {
if ( ownerCount > MAX_OWNER_COUNT require(ownerCount <= MAX_OWNER_COUNT
|| _required > ownerCount && _required <= ownerCount
|| _required == 0 && _required != 0
|| ownerCount == 0) && ownerCount != 0);
throw;
_; _;
} }
@ -108,8 +111,7 @@ contract MultiSigWallet {
validRequirement(_owners.length, _required) validRequirement(_owners.length, _required)
{ {
for (uint i=0; i<_owners.length; i++) { for (uint i=0; i<_owners.length; i++) {
if (isOwner[_owners[i]] || _owners[i] == 0) require(!isOwner[_owners[i]] && _owners[i] != 0);
throw;
isOwner[_owners[i]] = true; isOwner[_owners[i]] = true;
} }
owners = _owners; owners = _owners;
@ -151,7 +153,7 @@ contract MultiSigWallet {
/// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet. /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.
/// @param owner Address of owner to be replaced. /// @param owner Address of owner to be replaced.
/// @param owner Address of new owner. /// @param newOwner Address of new owner.
function replaceOwner(address owner, address newOwner) function replaceOwner(address owner, address newOwner)
public public
onlyWallet onlyWallet
@ -222,20 +224,44 @@ contract MultiSigWallet {
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
function executeTransaction(uint transactionId) function executeTransaction(uint transactionId)
public public
ownerExists(msg.sender)
confirmed(transactionId, msg.sender)
notExecuted(transactionId) notExecuted(transactionId)
{ {
if (isConfirmed(transactionId)) { if (isConfirmed(transactionId)) {
Transaction tx = transactions[transactionId]; Transaction storage txn = transactions[transactionId];
tx.executed = true; txn.executed = true;
if (tx.destination.call.value(tx.value)(tx.data)) if (external_call(txn.destination, txn.value, txn.data.length, txn.data))
Execution(transactionId); Execution(transactionId);
else { else {
ExecutionFailure(transactionId); ExecutionFailure(transactionId);
tx.executed = false; txn.executed = false;
} }
} }
} }
// call has been separated into its own function in order to take advantage
// of the Solidity's code generator to produce a loop that copies tx.data into memory.
function external_call(address destination, uint value, uint dataLength, bytes data) internal returns (bool) {
bool result;
assembly {
let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that
result := call(
sub(gas, 34710), // 34710 is the value that solidity is currently emitting
// It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +
// callNewAccountGas (25000, in case the destination address does not exist and needs creating)
destination,
value,
d,
dataLength, // Size of the input (in bytes) - this is what fixes the padding problem
x,
0 // Output is ignored, therefore the output size is zero
)
}
return result;
}
/// @dev Returns the confirmation status of a transaction. /// @dev Returns the confirmation status of a transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
/// @return Confirmation status. /// @return Confirmation status.

View File

@ -16,47 +16,57 @@
*/ */
// solhint-disable pragma solidity 0.4.24;
pragma solidity ^0.4.10;
import "./MultiSigWallet.sol"; import "./MultiSigWallet.sol";
/// @title Multisignature wallet with time lock- Allows multiple parties to execute a transaction after a time lock has passed. /// @title Multisignature wallet with time lock- Allows multiple parties to execute a transaction after a time lock has passed.
/// @author Amir Bandeali - <amir@0xProject.com> /// @author Amir Bandeali - <amir@0xProject.com>
contract MultiSigWalletWithTimeLock is MultiSigWallet { // solhint-disable not-rely-on-time
contract MultiSigWalletWithTimeLock is
MultiSigWallet
{
event ConfirmationTimeSet(uint256 indexed transactionId, uint256 confirmationTime);
event TimeLockChange(uint256 secondsTimeLocked);
event ConfirmationTimeSet(uint indexed transactionId, uint confirmationTime); uint256 public secondsTimeLocked;
event TimeLockChange(uint secondsTimeLocked);
uint public secondsTimeLocked; mapping (uint256 => uint256) public confirmationTimes;
mapping (uint => uint) public confirmationTimes; modifier notFullyConfirmed(uint256 transactionId) {
require(
modifier notFullyConfirmed(uint transactionId) { !isConfirmed(transactionId),
require(!isConfirmed(transactionId)); "TX_FULLY_CONFIRMED"
);
_; _;
} }
modifier fullyConfirmed(uint transactionId) { modifier fullyConfirmed(uint256 transactionId) {
require(isConfirmed(transactionId)); require(
isConfirmed(transactionId),
"TX_NOT_FULLY_CONFIRMED"
);
_; _;
} }
modifier pastTimeLock(uint transactionId) { modifier pastTimeLock(uint256 transactionId) {
require(block.timestamp >= confirmationTimes[transactionId] + secondsTimeLocked); require(
block.timestamp >= confirmationTimes[transactionId] + secondsTimeLocked,
"TIME_LOCK_INCOMPLETE"
);
_; _;
} }
/*
* Public functions
*/
/// @dev Contract constructor sets initial owners, required number of confirmations, and time lock. /// @dev Contract constructor sets initial owners, required number of confirmations, and time lock.
/// @param _owners List of initial owners. /// @param _owners List of initial owners.
/// @param _required Number of required confirmations. /// @param _required Number of required confirmations.
/// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds. /// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds.
function MultiSigWalletWithTimeLock(address[] _owners, uint _required, uint _secondsTimeLocked) constructor (
address[] _owners,
uint256 _required,
uint256 _secondsTimeLocked
)
public public
MultiSigWallet(_owners, _required) MultiSigWallet(_owners, _required)
{ {
@ -65,17 +75,17 @@ contract MultiSigWalletWithTimeLock is MultiSigWallet {
/// @dev Changes the duration of the time lock for transactions. /// @dev Changes the duration of the time lock for transactions.
/// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds. /// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds.
function changeTimeLock(uint _secondsTimeLocked) function changeTimeLock(uint256 _secondsTimeLocked)
public public
onlyWallet onlyWallet
{ {
secondsTimeLocked = _secondsTimeLocked; secondsTimeLocked = _secondsTimeLocked;
TimeLockChange(_secondsTimeLocked); emit TimeLockChange(_secondsTimeLocked);
} }
/// @dev Allows an owner to confirm a transaction. /// @dev Allows an owner to confirm a transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
function confirmTransaction(uint transactionId) function confirmTransaction(uint256 transactionId)
public public
ownerExists(msg.sender) ownerExists(msg.sender)
transactionExists(transactionId) transactionExists(transactionId)
@ -83,52 +93,35 @@ contract MultiSigWalletWithTimeLock is MultiSigWallet {
notFullyConfirmed(transactionId) notFullyConfirmed(transactionId)
{ {
confirmations[transactionId][msg.sender] = true; confirmations[transactionId][msg.sender] = true;
Confirmation(msg.sender, transactionId); emit Confirmation(msg.sender, transactionId);
if (isConfirmed(transactionId)) { if (isConfirmed(transactionId)) {
setConfirmationTime(transactionId, block.timestamp); setConfirmationTime(transactionId, block.timestamp);
} }
} }
/// @dev Allows an owner to revoke a confirmation for a transaction.
/// @param transactionId Transaction ID.
function revokeConfirmation(uint transactionId)
public
ownerExists(msg.sender)
confirmed(transactionId, msg.sender)
notExecuted(transactionId)
notFullyConfirmed(transactionId)
{
confirmations[transactionId][msg.sender] = false;
Revocation(msg.sender, transactionId);
}
/// @dev Allows anyone to execute a confirmed transaction. /// @dev Allows anyone to execute a confirmed transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
function executeTransaction(uint transactionId) function executeTransaction(uint256 transactionId)
public public
notExecuted(transactionId) notExecuted(transactionId)
fullyConfirmed(transactionId) fullyConfirmed(transactionId)
pastTimeLock(transactionId) pastTimeLock(transactionId)
{ {
Transaction storage tx = transactions[transactionId]; Transaction storage txn = transactions[transactionId];
tx.executed = true; txn.executed = true;
if (tx.destination.call.value(tx.value)(tx.data)) if (external_call(txn.destination, txn.value, txn.data.length, txn.data)) {
Execution(transactionId); emit Execution(transactionId);
else { } else {
ExecutionFailure(transactionId); emit ExecutionFailure(transactionId);
tx.executed = false; txn.executed = false;
} }
} }
/*
* Internal functions
*/
/// @dev Sets the time of when a submission first passed. /// @dev Sets the time of when a submission first passed.
function setConfirmationTime(uint transactionId, uint confirmationTime) function setConfirmationTime(uint256 transactionId, uint256 confirmationTime)
internal internal
{ {
confirmationTimes[transactionId] = confirmationTime; confirmationTimes[transactionId] = confirmationTime;
ConfirmationTimeSet(transactionId, confirmationTime); emit ConfirmationTimeSet(transactionId, confirmationTime);
} }
} }

View File

@ -26,7 +26,6 @@ contract MixinAuthorizable is
Ownable, Ownable,
MAuthorizable MAuthorizable
{ {
/// @dev Only authorized addresses can invoke functions with this modifier. /// @dev Only authorized addresses can invoke functions with this modifier.
modifier onlyAuthorized { modifier onlyAuthorized {
require( require(

View File

@ -24,7 +24,6 @@ import "./IAuthorizable.sol";
contract IAssetProxy is contract IAssetProxy is
IAuthorizable IAuthorizable
{ {
/// @dev Transfers assets. Either succeeds or throws. /// @dev Transfers assets. Either succeeds or throws.
/// @param assetData Byte array encoded for the respective asset proxy. /// @param assetData Byte array encoded for the respective asset proxy.
/// @param from Address to transfer asset from. /// @param from Address to transfer asset from.

View File

@ -24,7 +24,6 @@ import "../../../utils/Ownable/IOwnable.sol";
contract IAuthorizable is contract IAuthorizable is
IOwnable IOwnable
{ {
/// @dev Authorizes an address. /// @dev Authorizes an address.
/// @param target Address to authorize. /// @param target Address to authorize.
function addAuthorizedAddress(address target) function addAuthorizedAddress(address target)

View File

@ -24,7 +24,6 @@ import "../interfaces/IAuthorizable.sol";
contract MAuthorizable is contract MAuthorizable is
IAuthorizable IAuthorizable
{ {
// Event logged when a new address is authorized. // Event logged when a new address is authorized.
event AuthorizedAddressAdded( event AuthorizedAddressAdded(
address indexed target, address indexed target,

View File

@ -25,7 +25,6 @@ import "../../utils/LibBytes/LibBytes.sol";
contract AssetProxyOwner is contract AssetProxyOwner is
MultiSigWalletWithTimeLock MultiSigWalletWithTimeLock
{ {
using LibBytes for bytes; using LibBytes for bytes;
event AssetProxyRegistration(address assetProxyContract, bool isRegistered); event AssetProxyRegistration(address assetProxyContract, bool isRegistered);
@ -39,13 +38,13 @@ contract AssetProxyOwner is
/// @dev Function will revert if the transaction does not call `removeAuthorizedAddressAtIndex` /// @dev Function will revert if the transaction does not call `removeAuthorizedAddressAtIndex`
/// on an approved AssetProxy contract. /// on an approved AssetProxy contract.
modifier validRemoveAuthorizedAddressAtIndexTx(uint256 transactionId) { modifier validRemoveAuthorizedAddressAtIndexTx(uint256 transactionId) {
Transaction storage tx = transactions[transactionId]; Transaction storage txn = transactions[transactionId];
require( require(
isAssetProxyRegistered[tx.destination], isAssetProxyRegistered[txn.destination],
"UNREGISTERED_ASSET_PROXY" "UNREGISTERED_ASSET_PROXY"
); );
require( require(
tx.data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR, txn.data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR,
"INVALID_FUNCTION_SELECTOR" "INVALID_FUNCTION_SELECTOR"
); );
_; _;
@ -97,14 +96,13 @@ contract AssetProxyOwner is
fullyConfirmed(transactionId) fullyConfirmed(transactionId)
validRemoveAuthorizedAddressAtIndexTx(transactionId) validRemoveAuthorizedAddressAtIndexTx(transactionId)
{ {
Transaction storage tx = transactions[transactionId]; Transaction storage txn = transactions[transactionId];
tx.executed = true; txn.executed = true;
// solhint-disable-next-line avoid-call-value if (external_call(txn.destination, txn.value, txn.data.length, txn.data)) {
if (tx.destination.call.value(tx.value)(tx.data))
emit Execution(transactionId); emit Execution(transactionId);
else { } else {
emit ExecutionFailure(transactionId); emit ExecutionFailure(transactionId);
tx.executed = false; txn.executed = false;
} }
} }
} }

View File

@ -37,7 +37,6 @@ contract Exchange is
MixinAssetProxyDispatcher, MixinAssetProxyDispatcher,
MixinWrapperFunctions MixinWrapperFunctions
{ {
string constant public VERSION = "2.0.1-alpha"; string constant public VERSION = "2.0.1-alpha";
// Mixins are instantiated in the order they are inherited // Mixins are instantiated in the order they are inherited

View File

@ -27,7 +27,6 @@ contract MixinAssetProxyDispatcher is
Ownable, Ownable,
MAssetProxyDispatcher MAssetProxyDispatcher
{ {
// Mapping from Asset Proxy Id's to their respective Asset Proxy // Mapping from Asset Proxy Id's to their respective Asset Proxy
mapping (bytes4 => IAssetProxy) public assetProxies; mapping (bytes4 => IAssetProxy) public assetProxies;

View File

@ -75,7 +75,11 @@ contract MixinExchangeCore is
// Update orderEpoch // Update orderEpoch
orderEpoch[makerAddress][senderAddress] = newOrderEpoch; orderEpoch[makerAddress][senderAddress] = newOrderEpoch;
emit CancelUpTo(makerAddress, senderAddress, newOrderEpoch); emit CancelUpTo(
makerAddress,
senderAddress,
newOrderEpoch
);
} }
/// @dev Fills the input order. /// @dev Fills the input order.
@ -224,7 +228,11 @@ contract MixinExchangeCore is
); );
// Settle order // Settle order
settleOrder(order, takerAddress, fillResults); settleOrder(
order,
takerAddress,
fillResults
);
return fillResults; return fillResults;
} }

View File

@ -251,7 +251,7 @@ contract MixinSignatureValidator is
walletAddress, // address of Wallet contract walletAddress, // address of Wallet contract
cdStart, // pointer to start of input cdStart, // pointer to start of input
mload(calldata), // length of input mload(calldata), // length of input
cdStart, // write input over output cdStart, // write output over input
32 // output size is 32 bytes 32 // output size is 32 bytes
) )
@ -301,7 +301,7 @@ contract MixinSignatureValidator is
validatorAddress, // address of Validator contract validatorAddress, // address of Validator contract
cdStart, // pointer to start of input cdStart, // pointer to start of input
mload(calldata), // length of input mload(calldata), // length of input
cdStart, // write input over output cdStart, // write output over input
32 // output size is 32 bytes 32 // output size is 32 bytes
) )

View File

@ -28,7 +28,6 @@ contract MixinTransactions is
MSignatureValidator, MSignatureValidator,
MTransactions MTransactions
{ {
// Mapping of transaction hash => executed // Mapping of transaction hash => executed
// This prevents transactions from being executed more than once. // This prevents transactions from being executed more than once.
mapping (bytes32 => bool) public transactions; mapping (bytes32 => bool) public transactions;
@ -36,15 +35,6 @@ contract MixinTransactions is
// Address of current transaction signer // Address of current transaction signer
address public currentContextAddress; address public currentContextAddress;
// Hash for the EIP712 ZeroEx Transaction Schema
bytes32 constant internal EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked(
"ZeroExTransaction(",
"uint256 salt,",
"address signerAddress,",
"bytes data",
")"
));
/// @dev Executes an exchange method call in the context of signer. /// @dev Executes an exchange method call in the context of signer.
/// @param salt Arbitrary number to ensure uniqueness of transaction hash. /// @param salt Arbitrary number to ensure uniqueness of transaction hash.
/// @param signerAddress Address of transaction signer. /// @param signerAddress Address of transaction signer.

View File

@ -36,7 +36,6 @@ contract MixinWrapperFunctions is
MExchangeCore, MExchangeCore,
MWrapperFunctions MWrapperFunctions
{ {
/// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled. /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
/// @param order Order struct containing order specifications. /// @param order Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell. /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
@ -82,7 +81,7 @@ contract MixinWrapperFunctions is
// Delegate to `fillOrder` and handle any exceptions gracefully // Delegate to `fillOrder` and handle any exceptions gracefully
assembly { assembly {
let success := delegatecall( let success := delegatecall(
gas, // forward all gas, TODO: look into gas consumption of assert/throw gas, // forward all gas
address, // call address of this contract address, // call address of this contract
add(fillOrderCalldata, 32), // pointer to start of input (skip array length in first 32 bytes) add(fillOrderCalldata, 32), // pointer to start of input (skip array length in first 32 bytes)
mload(fillOrderCalldata), // length of input mload(fillOrderCalldata), // length of input

View File

@ -20,6 +20,7 @@ pragma solidity 0.4.24;
contract LibEIP712 { contract LibEIP712 {
// EIP191 header for EIP712 prefix // EIP191 header for EIP712 prefix
string constant internal EIP191_HEADER = "\x19\x01"; string constant internal EIP191_HEADER = "\x19\x01";

View File

@ -24,7 +24,6 @@ import "../../../utils/SafeMath/SafeMath.sol";
contract LibFillResults is contract LibFillResults is
SafeMath SafeMath
{ {
struct FillResults { struct FillResults {
uint256 makerAssetFilledAmount; // Total amount of makerAsset(s) filled. uint256 makerAssetFilledAmount; // Total amount of makerAsset(s) filled.
uint256 takerAssetFilledAmount; // Total amount of takerAsset(s) filled. uint256 takerAssetFilledAmount; // Total amount of takerAsset(s) filled.

View File

@ -24,7 +24,6 @@ import "../../../utils/SafeMath/SafeMath.sol";
contract LibMath is contract LibMath is
SafeMath SafeMath
{ {
/// @dev Calculates partial value given a numerator and denominator rounded down. /// @dev Calculates partial value given a numerator and denominator rounded down.
/// Reverts if rounding error is >= 0.1% /// Reverts if rounding error is >= 0.1%
/// @param numerator Numerator. /// @param numerator Numerator.
@ -206,7 +205,11 @@ contract LibMath is
// 1000 * remainder < numerator * target // 1000 * remainder < numerator * target
// so we have a rounding error iff: // so we have a rounding error iff:
// 1000 * remainder >= numerator * target // 1000 * remainder >= numerator * target
uint256 remainder = mulmod(target, numerator, denominator); uint256 remainder = mulmod(
target,
numerator,
denominator
);
isError = safeMul(1000, remainder) >= safeMul(numerator, target); isError = safeMul(1000, remainder) >= safeMul(numerator, target);
return isError; return isError;
} }
@ -238,8 +241,11 @@ contract LibMath is
return false; return false;
} }
// Compute remainder as before // Compute remainder as before
uint256 remainder = mulmod(target, numerator, denominator); uint256 remainder = mulmod(
// TODO: safeMod target,
numerator,
denominator
);
remainder = safeSub(denominator, remainder) % denominator; remainder = safeSub(denominator, remainder) % denominator;
isError = safeMul(1000, remainder) >= safeMul(numerator, target); isError = safeMul(1000, remainder) >= safeMul(numerator, target);
return isError; return isError;

View File

@ -24,7 +24,6 @@ import "./LibEIP712.sol";
contract LibOrder is contract LibOrder is
LibEIP712 LibEIP712
{ {
// Hash for the EIP712 Order Schema // Hash for the EIP712 Order Schema
bytes32 constant internal EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked( bytes32 constant internal EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked(
"Order(", "Order(",

View File

@ -24,7 +24,6 @@ import "../interfaces/IAssetProxyDispatcher.sol";
contract MAssetProxyDispatcher is contract MAssetProxyDispatcher is
IAssetProxyDispatcher IAssetProxyDispatcher
{ {
// Logs registration of new asset proxy // Logs registration of new asset proxy
event AssetProxyRegistered( event AssetProxyRegistered(
bytes4 id, // Id of new registered AssetProxy. bytes4 id, // Id of new registered AssetProxy.

View File

@ -26,7 +26,6 @@ import "../interfaces/IMatchOrders.sol";
contract MMatchOrders is contract MMatchOrders is
IMatchOrders IMatchOrders
{ {
/// @dev Validates context for matchOrders. Succeeds or throws. /// @dev Validates context for matchOrders. Succeeds or throws.
/// @param leftOrder First order to match. /// @param leftOrder First order to match.
/// @param rightOrder Second order to match. /// @param rightOrder Second order to match.

View File

@ -23,6 +23,28 @@ import "../interfaces/ITransactions.sol";
contract MTransactions is contract MTransactions is
ITransactions ITransactions
{ {
// Hash for the EIP712 ZeroEx Transaction Schema
bytes32 constant internal EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked(
"ZeroExTransaction(",
"uint256 salt,",
"address signerAddress,",
"bytes data",
")"
));
/// @dev Calculates EIP712 hash of the Transaction.
/// @param salt Arbitrary number to ensure uniqueness of transaction hash.
/// @param signerAddress Address of transaction signer.
/// @param data AbiV2 encoded calldata.
/// @return EIP712 hash of the Transaction.
function hashZeroExTransaction(
uint256 salt,
address signerAddress,
bytes memory data
)
internal
pure
returns (bytes32 result);
/// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`). /// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`).
/// If calling a fill function, this address will represent the taker. /// If calling a fill function, this address will represent the taker.

View File

@ -24,8 +24,9 @@ import "../libs/LibFillResults.sol";
import "../interfaces/IWrapperFunctions.sol"; import "../interfaces/IWrapperFunctions.sol";
contract MWrapperFunctions { contract MWrapperFunctions is
IWrapperFunctions
{
/// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled. /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
/// @param order LibOrder.Order struct containing order specifications. /// @param order LibOrder.Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell. /// @param takerAssetFillAmount Desired amount of takerAsset to sell.

View File

@ -25,7 +25,6 @@ import "./DummyERC20Token.sol";
contract DummyMultipleReturnERC20Token is contract DummyMultipleReturnERC20Token is
DummyERC20Token DummyERC20Token
{ {
constructor ( constructor (
string _name, string _name,
string _symbol, string _symbol,

View File

@ -25,7 +25,6 @@ import "./DummyERC20Token.sol";
contract DummyNoReturnERC20Token is contract DummyNoReturnERC20Token is
DummyERC20Token DummyERC20Token
{ {
constructor ( constructor (
string _name, string _name,
string _symbol, string _symbol,

View File

@ -24,7 +24,6 @@ import "../../tokens/ERC721Token/IERC721Receiver.sol";
contract DummyERC721Receiver is contract DummyERC721Receiver is
IERC721Receiver IERC721Receiver
{ {
// Function selector for ERC721Receiver.onERC721Received // Function selector for ERC721Receiver.onERC721Received
// 0x150b7a02 // 0x150b7a02
bytes4 constant internal ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")); bytes4 constant internal ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));

View File

@ -29,7 +29,6 @@ import "../../protocol/Exchange/libs/LibOrder.sol";
contract ReentrantERC20Token is contract ReentrantERC20Token is
ERC20Token ERC20Token
{ {
using LibBytes for bytes; using LibBytes for bytes;
// solhint-disable-next-line var-name-mixedcase // solhint-disable-next-line var-name-mixedcase

View File

@ -25,7 +25,6 @@ import "../../protocol/AssetProxyOwner/AssetProxyOwner.sol";
contract TestAssetProxyOwner is contract TestAssetProxyOwner is
AssetProxyOwner AssetProxyOwner
{ {
constructor ( constructor (
address[] memory _owners, address[] memory _owners,
address[] memory _assetProxyContracts, address[] memory _assetProxyContracts,

View File

@ -31,7 +31,6 @@ contract TestLibs is
LibFillResults, LibFillResults,
LibAbiEncoder LibAbiEncoder
{ {
function publicAbiEncodeFillOrder( function publicAbiEncodeFillOrder(
Order memory order, Order memory order,
uint256 takerAssetFillAmount, uint256 takerAssetFillAmount,

View File

@ -26,7 +26,6 @@ contract TestSignatureValidator is
MixinSignatureValidator, MixinSignatureValidator,
MixinTransactions MixinTransactions
{ {
function publicIsValidSignature( function publicIsValidSignature(
bytes32 hash, bytes32 hash,
address signer, address signer,

View File

@ -24,7 +24,6 @@ import "./IERC20Token.sol";
contract ERC20Token is contract ERC20Token is
IERC20Token IERC20Token
{ {
mapping (address => uint256) internal balances; mapping (address => uint256) internal balances;
mapping (address => mapping (address => uint256)) internal allowed; mapping (address => mapping (address => uint256)) internal allowed;

View File

@ -26,7 +26,6 @@ contract MintableERC20Token is
SafeMath, SafeMath,
UnlimitedAllowanceERC20Token UnlimitedAllowanceERC20Token
{ {
/// @dev Mints new tokens /// @dev Mints new tokens
/// @param _to Address of the beneficiary that will own the minted token /// @param _to Address of the beneficiary that will own the minted token
/// @param _value Amount of tokens to mint /// @param _value Amount of tokens to mint

View File

@ -24,7 +24,6 @@ import "../ERC20Token/ERC20Token.sol";
contract UnlimitedAllowanceERC20Token is contract UnlimitedAllowanceERC20Token is
ERC20Token ERC20Token
{ {
uint256 constant internal MAX_UINT = 2**256 - 1; uint256 constant internal MAX_UINT = 2**256 - 1;
/// @dev ERC20 transferFrom, modified such that an allowance of MAX_UINT represents an unlimited allowance. See https://github.com/ethereum/EIPs/issues/717 /// @dev ERC20 transferFrom, modified such that an allowance of MAX_UINT represents an unlimited allowance. See https://github.com/ethereum/EIPs/issues/717

View File

@ -24,7 +24,6 @@ import "./ERC721Token.sol";
contract MintableERC721Token is contract MintableERC721Token is
ERC721Token ERC721Token
{ {
/// @dev Function to mint a new token /// @dev Function to mint a new token
/// Reverts if the given token ID already exists /// Reverts if the given token ID already exists
/// @param _to Address of the beneficiary that will own the minted token /// @param _to Address of the beneficiary that will own the minted token

View File

@ -22,11 +22,13 @@ pragma solidity 0.4.11;
import { UnlimitedAllowanceToken_v1 as UnlimitedAllowanceToken } from "../../../1.0.0/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol"; import { UnlimitedAllowanceToken_v1 as UnlimitedAllowanceToken } from "../../../1.0.0/UnlimitedAllowanceToken/UnlimitedAllowanceToken_v1.sol";
contract ZRXToken is UnlimitedAllowanceToken { contract ZRXToken is
UnlimitedAllowanceToken
{
// solhint-disable const-name-snakecase // solhint-disable const-name-snakecase
uint8 constant public decimals = 18; uint8 constant public decimals = 18;
uint public totalSupply = 10**27; // 1 billion tokens, 18 decimal places uint256 public totalSupply = 10**27; // 1 billion tokens, 18 decimal places
string constant public name = "0x Protocol Token"; string constant public name = "0x Protocol Token";
string constant public symbol = "ZRX"; string constant public symbol = "ZRX";
// solhint-enableconst-name-snakecase // solhint-enableconst-name-snakecase

View File

@ -188,7 +188,8 @@ library LibBytes {
memCopy( memCopy(
result.contentAddress(), result.contentAddress(),
b.contentAddress() + from, b.contentAddress() + from,
result.length); result.length
);
return result; return result;
} }
@ -433,7 +434,8 @@ library LibBytes {
pure pure
returns (uint256 result) returns (uint256 result)
{ {
return uint256(readBytes32(b, index)); result = uint256(readBytes32(b, index));
return result;
} }
/// @dev Writes a uint256 into a specific position in a byte array. /// @dev Writes a uint256 into a specific position in a byte array.

View File

@ -1,13 +1,8 @@
pragma solidity 0.4.24; pragma solidity 0.4.24;
/*
* Ownable
*
* Base contract with an owner.
* Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.
*/
contract IOwnable { contract IOwnable {
function transferOwnership(address newOwner) function transferOwnership(address newOwner)
public; public;
} }

View File

@ -1,16 +1,11 @@
pragma solidity 0.4.24; pragma solidity 0.4.24;
/*
* Ownable
*
* Base contract with an owner.
* Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.
*/
import "./IOwnable.sol"; import "./IOwnable.sol";
contract Ownable is IOwnable { contract Ownable is
IOwnable
{
address public owner; address public owner;
constructor () constructor ()

View File

@ -15,6 +15,7 @@
limitations under the License. limitations under the License.
*/ */
pragma solidity 0.4.24; pragma solidity 0.4.24;

View File

@ -2,6 +2,7 @@ pragma solidity 0.4.24;
contract SafeMath { contract SafeMath {
function safeMul(uint256 a, uint256 b) function safeMul(uint256 a, uint256 b)
internal internal
pure pure

View File

@ -12,7 +12,11 @@ import { ExchangeContract } from '../../generated_contract_wrappers/exchange';
import { ForwarderContract } from '../../generated_contract_wrappers/forwarder'; import { ForwarderContract } from '../../generated_contract_wrappers/forwarder';
import { WETH9Contract } from '../../generated_contract_wrappers/weth9'; import { WETH9Contract } from '../../generated_contract_wrappers/weth9';
import { artifacts } from '../utils/artifacts'; import { artifacts } from '../utils/artifacts';
import { expectTransactionFailedAsync } from '../utils/assertions'; import {
expectContractCreationFailedAsync,
expectTransactionFailedAsync,
sendTransactionResult,
} from '../utils/assertions';
import { chaiSetup } from '../utils/chai_setup'; import { chaiSetup } from '../utils/chai_setup';
import { constants } from '../utils/constants'; import { constants } from '../utils/constants';
import { ERC20Wrapper } from '../utils/erc20_wrapper'; import { ERC20Wrapper } from '../utils/erc20_wrapper';
@ -37,6 +41,7 @@ describe(ContractName.Forwarder, () => {
let otherAddress: string; let otherAddress: string;
let defaultMakerAssetAddress: string; let defaultMakerAssetAddress: string;
let zrxAssetData: string; let zrxAssetData: string;
let wethAssetData: string;
let weth: DummyERC20TokenContract; let weth: DummyERC20TokenContract;
let zrxToken: DummyERC20TokenContract; let zrxToken: DummyERC20TokenContract;
@ -90,7 +95,7 @@ describe(ContractName.Forwarder, () => {
weth = new DummyERC20TokenContract(wethContract.abi, wethContract.address, provider); weth = new DummyERC20TokenContract(wethContract.abi, wethContract.address, provider);
erc20Wrapper.addDummyTokenContract(weth); erc20Wrapper.addDummyTokenContract(weth);
const wethAssetData = assetDataUtils.encodeERC20AssetData(wethContract.address); wethAssetData = assetDataUtils.encodeERC20AssetData(wethContract.address);
zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address); zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync( const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync(
artifacts.Exchange, artifacts.Exchange,
@ -98,8 +103,7 @@ describe(ContractName.Forwarder, () => {
txDefaults, txDefaults,
zrxAssetData, zrxAssetData,
); );
const exchangeContract = new ExchangeContract(exchangeInstance.abi, exchangeInstance.address, provider); exchangeWrapper = new ExchangeWrapper(exchangeInstance, provider);
exchangeWrapper = new ExchangeWrapper(exchangeContract, provider);
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner); await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner); await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
@ -162,6 +166,27 @@ describe(ContractName.Forwarder, () => {
await blockchainLifecycle.revertAsync(); await blockchainLifecycle.revertAsync();
}); });
describe('constructor', () => {
it('should revert if assetProxy is unregistered', async () => {
const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync(
artifacts.Exchange,
provider,
txDefaults,
zrxAssetData,
);
return expectContractCreationFailedAsync(
(ForwarderContract.deployFrom0xArtifactAsync(
artifacts.Forwarder,
provider,
txDefaults,
exchangeInstance.address,
zrxAssetData,
wethAssetData,
) as any) as sendTransactionResult,
RevertReason.UnregisteredAssetProxy,
);
});
});
describe('marketSellOrdersWithEth without extra fees', () => { describe('marketSellOrdersWithEth without extra fees', () => {
it('should fill a single order', async () => { it('should fill a single order', async () => {
const ordersWithoutFee = [orderWithoutFee]; const ordersWithoutFee = [orderWithoutFee];

View File

@ -34,6 +34,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('AssetProxyOwner', () => { describe('AssetProxyOwner', () => {
let owners: string[]; let owners: string[];
let authorized: string; let authorized: string;
let notOwner: string;
const REQUIRED_APPROVALS = new BigNumber(2); const REQUIRED_APPROVALS = new BigNumber(2);
const SECONDS_TIME_LOCKED = new BigNumber(1000000); const SECONDS_TIME_LOCKED = new BigNumber(1000000);
@ -51,7 +52,9 @@ describe('AssetProxyOwner', () => {
before(async () => { before(async () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync(); const accounts = await web3Wrapper.getAvailableAddressesAsync();
owners = [accounts[0], accounts[1]]; owners = [accounts[0], accounts[1]];
const initialOwner = (authorized = accounts[0]); authorized = accounts[2];
notOwner = accounts[3];
const initialOwner = accounts[0];
erc20Proxy = await MixinAuthorizableContract.deployFrom0xArtifactAsync( erc20Proxy = await MixinAuthorizableContract.deployFrom0xArtifactAsync(
artifacts.MixinAuthorizable, artifacts.MixinAuthorizable,
provider, provider,
@ -269,8 +272,12 @@ describe('AssetProxyOwner', () => {
await multiSigWrapper.confirmTransactionAsync(erc721AddAuthorizedAddressTxId, owners[1]); await multiSigWrapper.confirmTransactionAsync(erc721AddAuthorizedAddressTxId, owners[1]);
await increaseTimeAndMineBlockAsync(SECONDS_TIME_LOCKED.toNumber()); await increaseTimeAndMineBlockAsync(SECONDS_TIME_LOCKED.toNumber());
await multiSigWrapper.executeTransactionAsync(registerAssetProxyTxId, owners[0]); await multiSigWrapper.executeTransactionAsync(registerAssetProxyTxId, owners[0]);
await multiSigWrapper.executeTransactionAsync(erc20AddAuthorizedAddressTxId, owners[0]); await multiSigWrapper.executeTransactionAsync(erc20AddAuthorizedAddressTxId, owners[0], {
await multiSigWrapper.executeTransactionAsync(erc721AddAuthorizedAddressTxId, owners[0]); gas: constants.MAX_EXECUTE_TRANSACTION_GAS,
});
await multiSigWrapper.executeTransactionAsync(erc721AddAuthorizedAddressTxId, owners[0], {
gas: constants.MAX_EXECUTE_TRANSACTION_GAS,
});
}); });
describe('validRemoveAuthorizedAddressAtIndexTx', () => { describe('validRemoveAuthorizedAddressAtIndexTx', () => {
@ -342,10 +349,11 @@ describe('AssetProxyOwner', () => {
const log = res.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>; const log = res.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>;
const txId = log.args.transactionId; const txId = log.args.transactionId;
return expectTransactionFailedWithoutReasonAsync( return expectTransactionFailedAsync(
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
from: owners[1], from: owners[1],
}), }),
RevertReason.TxNotFullyConfirmed,
); );
}); });
@ -395,7 +403,10 @@ describe('AssetProxyOwner', () => {
); );
}); });
it('should execute removeAuthorizedAddressAtIndex for registered address if fully confirmed', async () => { it('should execute removeAuthorizedAddressAtIndex for registered address if fully confirmed and called by owner', async () => {
const isAuthorizedBefore = await erc20Proxy.authorized.callAsync(authorized);
expect(isAuthorizedBefore).to.equal(true);
const removeAuthorizedAddressAtIndexData = erc20Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData( const removeAuthorizedAddressAtIndexData = erc20Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData(
authorized, authorized,
erc20Index, erc20Index,
@ -418,8 +429,38 @@ describe('AssetProxyOwner', () => {
const isExecuted = tx[3]; const isExecuted = tx[3];
expect(isExecuted).to.equal(true); expect(isExecuted).to.equal(true);
const isAuthorized = await erc20Proxy.authorized.callAsync(authorized); const isAuthorizedAfter = await erc20Proxy.authorized.callAsync(authorized);
expect(isAuthorized).to.equal(false); expect(isAuthorizedAfter).to.equal(false);
});
it('should execute removeAuthorizedAddressAtIndex for registered address if fully confirmed and called by non-owner', async () => {
const isAuthorizedBefore = await erc20Proxy.authorized.callAsync(authorized);
expect(isAuthorizedBefore).to.equal(true);
const removeAuthorizedAddressAtIndexData = erc20Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData(
authorized,
erc20Index,
);
const submitRes = await multiSigWrapper.submitTransactionAsync(
erc20Proxy.address,
removeAuthorizedAddressAtIndexData,
owners[0],
);
const submitLog = submitRes.logs[0] as LogWithDecodedArgs<AssetProxyOwnerSubmissionEventArgs>;
const txId = submitLog.args.transactionId;
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
const execRes = await multiSigWrapper.executeRemoveAuthorizedAddressAtIndexAsync(txId, notOwner);
const execLog = execRes.logs[1] as LogWithDecodedArgs<AssetProxyOwnerExecutionEventArgs>;
expect(execLog.args.transactionId).to.be.bignumber.equal(txId);
const tx = await testAssetProxyOwner.transactions.callAsync(txId);
const isExecuted = tx[3];
expect(isExecuted).to.equal(true);
const isAuthorizedAfter = await erc20Proxy.authorized.callAsync(authorized);
expect(isAuthorizedAfter).to.equal(false);
}); });
it('should throw if already executed', async () => { it('should throw if already executed', async () => {

View File

@ -1,14 +1,21 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { BlockchainLifecycle } from '@0xproject/dev-utils';
import { RevertReason } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils'; import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai'; import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types'; import { LogWithDecodedArgs } from 'ethereum-types';
import * as _ from 'lodash';
import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token';
import { import {
MultiSigWalletWithTimeLockConfirmationEventArgs,
MultiSigWalletWithTimeLockConfirmationTimeSetEventArgs,
MultiSigWalletWithTimeLockContract, MultiSigWalletWithTimeLockContract,
MultiSigWalletWithTimeLockExecutionEventArgs,
MultiSigWalletWithTimeLockExecutionFailureEventArgs,
MultiSigWalletWithTimeLockSubmissionEventArgs, MultiSigWalletWithTimeLockSubmissionEventArgs,
} from '../../generated_contract_wrappers/multi_sig_wallet_with_time_lock'; } from '../../generated_contract_wrappers/multi_sig_wallet_with_time_lock';
import { artifacts } from '../utils/artifacts'; import { artifacts } from '../utils/artifacts';
import { expectTransactionFailedWithoutReasonAsync } from '../utils/assertions'; import { expectTransactionFailedAsync, expectTransactionFailedWithoutReasonAsync } from '../utils/assertions';
import { increaseTimeAndMineBlockAsync } from '../utils/block_timestamp'; import { increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
import { chaiSetup } from '../utils/chai_setup'; import { chaiSetup } from '../utils/chai_setup';
import { constants } from '../utils/constants'; import { constants } from '../utils/constants';
@ -21,6 +28,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
describe('MultiSigWalletWithTimeLock', () => { describe('MultiSigWalletWithTimeLock', () => {
let owners: string[]; let owners: string[];
let notOwner: string;
const REQUIRED_APPROVALS = new BigNumber(2); const REQUIRED_APPROVALS = new BigNumber(2);
const SECONDS_TIME_LOCKED = new BigNumber(1000000); const SECONDS_TIME_LOCKED = new BigNumber(1000000);
@ -32,7 +40,8 @@ describe('MultiSigWalletWithTimeLock', () => {
}); });
before(async () => { before(async () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync(); const accounts = await web3Wrapper.getAvailableAddressesAsync();
owners = [accounts[0], accounts[1]]; owners = [accounts[0], accounts[1], accounts[2]];
notOwner = accounts[3];
}); });
let multiSig: MultiSigWalletWithTimeLockContract; let multiSig: MultiSigWalletWithTimeLockContract;
@ -45,6 +54,171 @@ describe('MultiSigWalletWithTimeLock', () => {
await blockchainLifecycle.revertAsync(); await blockchainLifecycle.revertAsync();
}); });
describe('external_call', () => {
it('should be internal', async () => {
const secondsTimeLocked = new BigNumber(0);
multiSig = await MultiSigWalletWithTimeLockContract.deployFrom0xArtifactAsync(
artifacts.MultiSigWalletWithTimeLock,
provider,
txDefaults,
owners,
REQUIRED_APPROVALS,
secondsTimeLocked,
);
expect(_.isUndefined((multiSig as any).external_call)).to.be.equal(true);
});
});
describe('confirmTransaction', () => {
let txId: BigNumber;
beforeEach(async () => {
const secondsTimeLocked = new BigNumber(0);
multiSig = await MultiSigWalletWithTimeLockContract.deployFrom0xArtifactAsync(
artifacts.MultiSigWalletWithTimeLock,
provider,
txDefaults,
owners,
REQUIRED_APPROVALS,
secondsTimeLocked,
);
multiSigWrapper = new MultiSigWrapper(multiSig, provider);
const destination = notOwner;
const data = constants.NULL_BYTES;
const txReceipt = await multiSigWrapper.submitTransactionAsync(destination, data, owners[0]);
txId = (txReceipt.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockSubmissionEventArgs>).args
.transactionId;
});
it('should revert if called by a non-owner', async () => {
await expectTransactionFailedWithoutReasonAsync(multiSigWrapper.confirmTransactionAsync(txId, notOwner));
});
it('should revert if transaction does not exist', async () => {
const nonexistentTxId = new BigNumber(123456789);
await expectTransactionFailedWithoutReasonAsync(
multiSigWrapper.confirmTransactionAsync(nonexistentTxId, owners[1]),
);
});
it('should revert if transaction is already confirmed by caller', async () => {
await expectTransactionFailedWithoutReasonAsync(multiSigWrapper.confirmTransactionAsync(txId, owners[0]));
});
it('should confirm transaction for caller and log a Confirmation event', async () => {
const txReceipt = await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
const log = txReceipt.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockConfirmationEventArgs>;
expect(log.event).to.be.equal('Confirmation');
expect(log.args.sender).to.be.equal(owners[1]);
expect(log.args.transactionId).to.be.bignumber.equal(txId);
});
it('should revert if fully confirmed', async () => {
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
await expectTransactionFailedAsync(
multiSigWrapper.confirmTransactionAsync(txId, owners[2]),
RevertReason.TxFullyConfirmed,
);
});
it('should set the confirmation time of the transaction if it becomes fully confirmed', async () => {
const txReceipt = await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
const blockNum = await web3Wrapper.getBlockNumberAsync();
const timestamp = new BigNumber(await web3Wrapper.getBlockTimestampAsync(blockNum));
const log = txReceipt.logs[1] as LogWithDecodedArgs<MultiSigWalletWithTimeLockConfirmationTimeSetEventArgs>;
expect(log.args.confirmationTime).to.be.bignumber.equal(timestamp);
expect(log.args.transactionId).to.be.bignumber.equal(txId);
});
});
describe('executeTransaction', () => {
let txId: BigNumber;
const secondsTimeLocked = new BigNumber(1000000);
beforeEach(async () => {
multiSig = await MultiSigWalletWithTimeLockContract.deployFrom0xArtifactAsync(
artifacts.MultiSigWalletWithTimeLock,
provider,
txDefaults,
owners,
REQUIRED_APPROVALS,
secondsTimeLocked,
);
multiSigWrapper = new MultiSigWrapper(multiSig, provider);
const destination = notOwner;
const data = constants.NULL_BYTES;
const txReceipt = await multiSigWrapper.submitTransactionAsync(destination, data, owners[0]);
txId = (txReceipt.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockSubmissionEventArgs>).args
.transactionId;
});
it('should revert if transaction has not been fully confirmed', async () => {
await increaseTimeAndMineBlockAsync(secondsTimeLocked.toNumber());
await expectTransactionFailedAsync(
multiSigWrapper.executeTransactionAsync(txId, owners[1]),
RevertReason.TxNotFullyConfirmed,
);
});
it('should revert if time lock has not passed', async () => {
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
await expectTransactionFailedAsync(
multiSigWrapper.executeTransactionAsync(txId, owners[1]),
RevertReason.TimeLockIncomplete,
);
});
it('should execute a transaction and log an Execution event if successful and called by owner', async () => {
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
await increaseTimeAndMineBlockAsync(secondsTimeLocked.toNumber());
const txReceipt = await multiSigWrapper.executeTransactionAsync(txId, owners[1]);
const log = txReceipt.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockExecutionEventArgs>;
expect(log.event).to.be.equal('Execution');
expect(log.args.transactionId).to.be.bignumber.equal(txId);
});
it('should execute a transaction and log an Execution event if successful and called by non-owner', async () => {
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
await increaseTimeAndMineBlockAsync(secondsTimeLocked.toNumber());
const txReceipt = await multiSigWrapper.executeTransactionAsync(txId, notOwner);
const log = txReceipt.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockExecutionEventArgs>;
expect(log.event).to.be.equal('Execution');
expect(log.args.transactionId).to.be.bignumber.equal(txId);
});
it('should revert if a required confirmation is revoked before executeTransaction is called', async () => {
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
await increaseTimeAndMineBlockAsync(secondsTimeLocked.toNumber());
await multiSigWrapper.revokeConfirmationAsync(txId, owners[0]);
await expectTransactionFailedAsync(
multiSigWrapper.executeTransactionAsync(txId, owners[1]),
RevertReason.TxNotFullyConfirmed,
);
});
it('should revert if transaction has been executed', async () => {
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
await increaseTimeAndMineBlockAsync(secondsTimeLocked.toNumber());
const txReceipt = await multiSigWrapper.executeTransactionAsync(txId, owners[1]);
const log = txReceipt.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockExecutionEventArgs>;
expect(log.args.transactionId).to.be.bignumber.equal(txId);
await expectTransactionFailedWithoutReasonAsync(multiSigWrapper.executeTransactionAsync(txId, owners[1]));
});
it("should log an ExecutionFailure event and not update the transaction's execution state if unsuccessful", async () => {
const contractWithoutFallback = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
artifacts.DummyERC20Token,
provider,
txDefaults,
constants.DUMMY_TOKEN_NAME,
constants.DUMMY_TOKEN_SYMBOL,
constants.DUMMY_TOKEN_DECIMALS,
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
);
const data = constants.NULL_BYTES;
const value = new BigNumber(10);
const submissionTxReceipt = await multiSigWrapper.submitTransactionAsync(
contractWithoutFallback.address,
data,
owners[0],
{ value },
);
const newTxId = (submissionTxReceipt.logs[0] as LogWithDecodedArgs<
MultiSigWalletWithTimeLockSubmissionEventArgs
>).args.transactionId;
await multiSigWrapper.confirmTransactionAsync(newTxId, owners[1]);
await increaseTimeAndMineBlockAsync(secondsTimeLocked.toNumber());
const txReceipt = await multiSigWrapper.executeTransactionAsync(newTxId, owners[1]);
const executionFailureLog = txReceipt.logs[0] as LogWithDecodedArgs<
MultiSigWalletWithTimeLockExecutionFailureEventArgs
>;
expect(executionFailureLog.event).to.be.equal('ExecutionFailure');
expect(executionFailureLog.args.transactionId).to.be.bignumber.equal(newTxId);
});
});
describe('changeTimeLock', () => { describe('changeTimeLock', () => {
describe('initially non-time-locked', async () => { describe('initially non-time-locked', async () => {
before(async () => { before(async () => {
@ -78,8 +252,9 @@ describe('MultiSigWalletWithTimeLock', () => {
const res = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]); const res = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]);
const log = res.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockSubmissionEventArgs>; const log = res.logs[0] as LogWithDecodedArgs<MultiSigWalletWithTimeLockSubmissionEventArgs>;
const txId = log.args.transactionId; const txId = log.args.transactionId;
return expectTransactionFailedWithoutReasonAsync( return expectTransactionFailedAsync(
multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }), multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }),
RevertReason.TxNotFullyConfirmed,
); );
}); });
@ -147,8 +322,9 @@ describe('MultiSigWalletWithTimeLock', () => {
}); });
it('should throw if it has enough confirmations but is not past the time lock', async () => { it('should throw if it has enough confirmations but is not past the time lock', async () => {
return expectTransactionFailedWithoutReasonAsync( return expectTransactionFailedAsync(
multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }), multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }),
RevertReason.TimeLockIncomplete,
); );
}); });

View File

@ -6,7 +6,6 @@ import * as _ from 'lodash';
import { AssetProxyOwnerContract } from '../../generated_contract_wrappers/asset_proxy_owner'; import { AssetProxyOwnerContract } from '../../generated_contract_wrappers/asset_proxy_owner';
import { MultiSigWalletContract } from '../../generated_contract_wrappers/multi_sig_wallet'; import { MultiSigWalletContract } from '../../generated_contract_wrappers/multi_sig_wallet';
import { constants } from './constants';
import { LogDecoder } from './log_decoder'; import { LogDecoder } from './log_decoder';
export class MultiSigWrapper { export class MultiSigWrapper {
@ -36,10 +35,19 @@ export class MultiSigWrapper {
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
return tx; return tx;
} }
public async executeTransactionAsync(txId: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> { public async revokeConfirmationAsync(txId: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
const txHash = await this._multiSig.revokeConfirmation.sendTransactionAsync(txId, { from });
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
return tx;
}
public async executeTransactionAsync(
txId: BigNumber,
from: string,
opts: { gas?: number } = {},
): Promise<TransactionReceiptWithDecodedLogs> {
const txHash = await this._multiSig.executeTransaction.sendTransactionAsync(txId, { const txHash = await this._multiSig.executeTransaction.sendTransactionAsync(txId, {
from, from,
gas: constants.MAX_EXECUTE_TRANSACTION_GAS, gas: opts.gas,
}); });
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
return tx; return tx;
@ -52,7 +60,6 @@ export class MultiSigWrapper {
const txHash = await (this const txHash = await (this
._multiSig as AssetProxyOwnerContract).executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { ._multiSig as AssetProxyOwnerContract).executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
from, from,
gas: constants.MAX_EXECUTE_TRANSACTION_GAS,
}); });
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
return tx; return tx;

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "1.0.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1535377027, "timestamp": 1535377027,
"version": "1.0.6", "version": "1.0.6",

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.7 - _September 5, 2018_
* Dependencies updated
## v1.0.6 - _August 27, 2018_ ## v1.0.6 - _August 27, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,6 +1,6 @@
{ {
"name": "@0xproject/dev-utils", "name": "@0xproject/dev-utils",
"version": "1.0.6", "version": "1.0.7",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -28,7 +28,7 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/dev-utils/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/dev-utils/README.md",
"devDependencies": { "devDependencies": {
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42", "@types/mocha": "^2.2.42",
"chai": "^4.0.1", "chai": "^4.0.1",
@ -42,12 +42,12 @@
"typescript": "3.0.1" "typescript": "3.0.1"
}, },
"dependencies": { "dependencies": {
"@0xproject/subproviders": "^2.0.1", "@0xproject/subproviders": "^2.0.2",
"@0xproject/types": "^1.0.1-rc.6", "@0xproject/types": "^1.0.1",
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"@0xproject/web3-wrapper": "^2.0.1", "@0xproject/web3-wrapper": "^2.0.2",
"ethereum-types": "^1.0.5", "ethereum-types": "^1.0.6",
"lodash": "^4.17.5" "lodash": "^4.17.5"
}, },
"publishConfig": { "publishConfig": {

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "1.0.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"timestamp": 1535133899, "timestamp": 1535133899,
"version": "1.0.5", "version": "1.0.5",

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.6 - _September 5, 2018_
* Dependencies updated
## v1.0.5 - _August 24, 2018_ ## v1.0.5 - _August 24, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,6 +1,6 @@
{ {
"name": "ethereum-types", "name": "ethereum-types",
"version": "1.0.5", "version": "1.0.6",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -28,7 +28,7 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/ethereum-types/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/ethereum-types/README.md",
"devDependencies": { "devDependencies": {
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"copyfiles": "^2.0.0", "copyfiles": "^2.0.0",
"make-promises-safe": "^1.1.0", "make-promises-safe": "^1.1.0",
"shx": "^0.2.2", "shx": "^0.2.2",

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"version": "1.0.1-rc.5", "version": "1.0.1-rc.5",
"changes": [ "changes": [

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.1 - _September 5, 2018_
* Dependencies updated
## v1.0.1-rc.5 - _August 27, 2018_ ## v1.0.1-rc.5 - _August 27, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,13 +1,13 @@
{ {
"name": "@0xproject/fill-scenarios", "name": "@0xproject/fill-scenarios",
"version": "1.0.1-rc.5", "version": "1.0.1",
"description": "0x order fill scenario generator", "description": "0x order fill scenario generator",
"main": "lib/index.js", "main": "lib/index.js",
"types": "lib/index.d.ts", "types": "lib/index.d.ts",
"scripts": { "scripts": {
"build": "yarn pre_build && tsc -b", "build": "yarn pre_build && tsc -b",
"pre_build": "run-s update_artifacts generate_contract_wrappers", "pre_build": "run-s update_artifacts generate_contract_wrappers",
"update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0-beta-testnet/$i.json lib/artifacts; done;", "update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json lib/artifacts; done;",
"generate_contract_wrappers": "abi-gen --abis 'lib/artifacts/@(Exchange|DummyERC20Token|DummyERC721Token).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers", "generate_contract_wrappers": "abi-gen --abis 'lib/artifacts/@(Exchange|DummyERC20Token|DummyERC721Token).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers",
"copy_monorepo_scripts": "copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", "copy_monorepo_scripts": "copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"clean": "shx rm -rf lib src/generated_contract_wrappers", "clean": "shx rm -rf lib src/generated_contract_wrappers",
@ -26,8 +26,8 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/fill-scenarios/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/fill-scenarios/README.md",
"devDependencies": { "devDependencies": {
"@0xproject/abi-gen": "^1.0.7", "@0xproject/abi-gen": "^1.0.8",
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"copyfiles": "^2.0.0", "copyfiles": "^2.0.0",
"make-promises-safe": "^1.1.0", "make-promises-safe": "^1.1.0",
@ -37,13 +37,13 @@
"typescript": "3.0.1" "typescript": "3.0.1"
}, },
"dependencies": { "dependencies": {
"@0xproject/base-contract": "^2.0.1", "@0xproject/base-contract": "^2.0.2",
"@0xproject/order-utils": "^1.0.1-rc.6", "@0xproject/order-utils": "^1.0.1",
"@0xproject/types": "^1.0.1-rc.6", "@0xproject/types": "^1.0.1",
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"@0xproject/web3-wrapper": "^2.0.1", "@0xproject/web3-wrapper": "^2.0.2",
"ethereum-types": "^1.0.5", "ethereum-types": "^1.0.6",
"ethers": "3.0.22", "ethers": "3.0.22",
"lodash": "^4.17.5" "lodash": "^4.17.5"
}, },

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"version": "1.0.1-rc.2", "version": "1.0.1-rc.2",
"changes": [ "changes": [

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.1 - _September 5, 2018_
* Dependencies updated
## v1.0.1-rc.2 - _August 27, 2018_ ## v1.0.1-rc.2 - _August 27, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,6 +1,6 @@
{ {
"name": "@0xproject/forwarder-helper", "name": "@0xproject/forwarder-helper",
"version": "1.0.1-rc.2", "version": "1.0.1",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -39,17 +39,17 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/forwarder-helper/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/forwarder-helper/README.md",
"dependencies": { "dependencies": {
"@0xproject/assert": "^1.0.7", "@0xproject/assert": "^1.0.8",
"@0xproject/json-schemas": "^1.0.1-rc.6", "@0xproject/json-schemas": "^1.0.1",
"@0xproject/order-utils": "^1.0.1-rc.6", "@0xproject/order-utils": "^1.0.1",
"@0xproject/types": "^1.0.1-rc.6", "@0xproject/types": "^1.0.1",
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"@types/node": "^8.0.53", "@types/node": "^8.0.53",
"lodash": "^4.17.10" "lodash": "^4.17.10"
}, },
"devDependencies": { "devDependencies": {
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@types/lodash": "^4.14.116", "@types/lodash": "^4.14.116",
"@types/mocha": "^2.2.42", "@types/mocha": "^2.2.42",
"chai": "^4.0.1", "chai": "^4.0.1",

View File

@ -1,4 +1,13 @@
[ [
{
"timestamp": 1536142250,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{ {
"version": "1.0.1-rc.6", "version": "1.0.1-rc.6",
"changes": [ "changes": [

View File

@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v1.0.1 - _September 5, 2018_
* Dependencies updated
## v1.0.1-rc.6 - _August 27, 2018_ ## v1.0.1-rc.6 - _August 27, 2018_
* Dependencies updated * Dependencies updated

View File

@ -1,6 +1,6 @@
{ {
"name": "@0xproject/json-schemas", "name": "@0xproject/json-schemas",
"version": "1.0.1-rc.6", "version": "1.0.1",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },
@ -38,14 +38,14 @@
}, },
"homepage": "https://github.com/0xProject/0x-monorepo/packages/json-schemas/README.md", "homepage": "https://github.com/0xProject/0x-monorepo/packages/json-schemas/README.md",
"dependencies": { "dependencies": {
"@0xproject/typescript-typings": "^1.0.5", "@0xproject/typescript-typings": "^2.0.0",
"@types/node": "^8.0.53", "@types/node": "^8.0.53",
"jsonschema": "^1.2.0", "jsonschema": "^1.2.0",
"lodash.values": "^4.3.0" "lodash.values": "^4.3.0"
}, },
"devDependencies": { "devDependencies": {
"@0xproject/tslint-config": "^1.0.6", "@0xproject/tslint-config": "^1.0.7",
"@0xproject/utils": "^1.0.7", "@0xproject/utils": "^1.0.8",
"@types/lodash.foreach": "^4.5.3", "@types/lodash.foreach": "^4.5.3",
"@types/lodash.values": "^4.3.3", "@types/lodash.values": "^4.3.3",
"@types/mocha": "^2.2.42", "@types/mocha": "^2.2.42",

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