diff options
93 files changed, 1132 insertions, 1357 deletions
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 2942e5001..9cce372a5 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -2,27 +2,24 @@ "name": "0x.js", "version": "0.31.0", "description": "A javascript library for interacting with the 0x protocol", - "keywords": [ - "0x.js", - "0xproject", - "ethereum", - "tokens", - "exchange" - ], + "keywords": ["0x.js", "0xproject", "ethereum", "tokens", "exchange"], "main": "lib/src/index.js", "types": "lib/src/index.d.ts", "scripts": { "prebuild": "run-s clean generate_contract_wrappers", "build": "run-p build:umd:prod build:commonjs; exit 0;", "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR", - "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json", - "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --templates contract_templates --output src/contract_wrappers/generated", + "upload_docs_json": + "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json", + "generate_contract_wrappers": + "node ../abi-gen/lib/index.js --abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --templates contract_templates --output src/contract_wrappers/generated", "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'", "test:circleci": "run-s test:coverage report_test_coverage", "test": "run-s clean test:commonjs", "test:coverage": "nyc npm run test --all", "report_test_coverage": "nyc report --reporter=text-lcov | coveralls", - "update_contracts": "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;", + "update_contracts": + "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;", "clean": "shx rm -rf _bundles lib test_temp", "build:umd:prod": "NODE_ENV=production webpack", "build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;", @@ -66,7 +63,7 @@ "nyc": "^11.0.1", "opn-cli": "^3.1.0", "request": "^2.81.0", - "request-promise-native": "^1.0.4", + "request-promise-native": "^1.0.5", "shx": "^0.2.2", "sinon": "^4.0.0", "source-map-support": "^0.5.0", @@ -89,7 +86,7 @@ "ethereumjs-abi": "^0.6.4", "ethereumjs-blockstream": "^2.0.6", "ethereumjs-util": "^5.1.1", - "js-sha3": "^0.6.1", + "js-sha3": "^0.7.0", "lodash": "^4.17.4", "uuid": "^3.1.0", "web3": "^0.20.0" diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts index f8a484c5d..6cfa65cc2 100644 --- a/packages/0x.js/src/0x.ts +++ b/packages/0x.js/src/0x.ts @@ -1,5 +1,6 @@ import { schemas, SchemaValidator } from '@0xproject/json-schemas'; -import { BigNumber, intervalUtils } from '@0xproject/utils'; +import { TransactionReceiptWithDecodedLogs } from '@0xproject/types'; +import { AbiDecoder, BigNumber, intervalUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as ethUtil from 'ethereumjs-util'; import * as _ from 'lodash'; @@ -12,16 +13,7 @@ import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_pr import { TokenWrapper } from './contract_wrappers/token_wrapper'; import { OrderStateWatcher } from './order_watcher/order_state_watcher'; import { zeroExConfigSchema } from './schemas/zero_ex_config_schema'; -import { - ECSignature, - Order, - SignedOrder, - TransactionReceiptWithDecodedLogs, - Web3Provider, - ZeroExConfig, - ZeroExError, -} from './types'; -import { AbiDecoder } from './utils/abi_decoder'; +import { ECSignature, Order, SignedOrder, Web3Provider, ZeroExConfig, ZeroExError } from './types'; import { assert } from './utils/assert'; import { constants } from './utils/constants'; import { decorators } from './utils/decorators'; @@ -334,8 +326,8 @@ export class ZeroEx { ); }, ); - - return txReceiptPromise; + const txReceipt = await txReceiptPromise; + return txReceipt; } /* * HACK: `TokenWrapper` needs a token transfer proxy address. `TokenTransferProxy` address is fetched from diff --git a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts index 27551c01d..5f11d810a 100644 --- a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts @@ -1,4 +1,5 @@ -import { intervalUtils } from '@0xproject/utils'; +import { LogWithDecodedArgs, RawLog } from '@0xproject/types'; +import { AbiDecoder, intervalUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Block, BlockAndLogStreamer } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; @@ -13,11 +14,8 @@ import { EventCallback, IndexedFilterValues, InternalZeroExError, - LogWithDecodedArgs, - RawLog, ZeroExError, } from '../types'; -import { AbiDecoder } from '../utils/abi_decoder'; import { constants } from '../utils/constants'; import { filterUtils } from '../utils/filter_utils'; diff --git a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts index b03571636..8fa7aa78b 100644 --- a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts @@ -1,5 +1,6 @@ import { schemas } from '@0xproject/json-schemas'; -import { BigNumber } from '@0xproject/utils'; +import { LogWithDecodedArgs } from '@0xproject/types'; +import { AbiDecoder, BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; @@ -10,11 +11,9 @@ import { EtherTokenEvents, EventCallback, IndexedFilterValues, - LogWithDecodedArgs, TransactionOpts, ZeroExError, } from '../types'; -import { AbiDecoder } from '../utils/abi_decoder'; import { assert } from '../utils/assert'; import { ContractWrapper } from './contract_wrapper'; diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts index 2b6117729..fceab851a 100644 --- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts @@ -1,5 +1,6 @@ import { schemas } from '@0xproject/json-schemas'; -import { BigNumber } from '@0xproject/utils'; +import { DecodedLogArgs, LogWithDecodedArgs } from '@0xproject/types'; +import { AbiDecoder, BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import * as Web3 from 'web3'; @@ -8,7 +9,6 @@ import { artifacts } from '../artifacts'; import { BlockParamLiteral, BlockRange, - DecodedLogArgs, ECSignature, EventCallback, ExchangeContractErrCodes, @@ -17,7 +17,6 @@ import { ExchangeEvents, IndexedFilterValues, LogErrorContractEventArgs, - LogWithDecodedArgs, MethodOpts, Order, OrderAddresses, @@ -28,7 +27,6 @@ import { SignedOrder, ValidateOrderFillableOpts, } from '../types'; -import { AbiDecoder } from '../utils/abi_decoder'; import { assert } from '../utils/assert'; import { decorators } from '../utils/decorators'; import { ExchangeTransferSimulator } from '../utils/exchange_transfer_simulator'; @@ -846,9 +844,9 @@ export class ExchangeWrapper extends ContractWrapper { public throwLogErrorsAsErrors(logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>): void { const errLog = _.find(logs, { event: ExchangeEvents.LogError, - }) as LogWithDecodedArgs<LogErrorContractEventArgs> | undefined; + }); if (!_.isUndefined(errLog)) { - const logArgs = errLog.args; + const logArgs = (errLog as LogWithDecodedArgs<LogErrorContractEventArgs>).args; const errCode = logArgs.errorId.toNumber(); const errMessage = this._exchangeContractErrCodesToMsg[errCode]; throw new Error(errMessage); diff --git a/packages/0x.js/src/contract_wrappers/token_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_wrapper.ts index 7943f4a60..4216ff462 100644 --- a/packages/0x.js/src/contract_wrappers/token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_wrapper.ts @@ -1,5 +1,6 @@ import { schemas } from '@0xproject/json-schemas'; -import { BigNumber } from '@0xproject/utils'; +import { LogWithDecodedArgs } from '@0xproject/types'; +import { AbiDecoder, BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; @@ -8,14 +9,12 @@ import { BlockRange, EventCallback, IndexedFilterValues, - LogWithDecodedArgs, MethodOpts, TokenContractEventArgs, TokenEvents, TransactionOpts, ZeroExError, } from '../types'; -import { AbiDecoder } from '../utils/abi_decoder'; import { assert } from '../utils/assert'; import { constants } from '../utils/constants'; diff --git a/packages/0x.js/src/globals.d.ts b/packages/0x.js/src/globals.d.ts index 4f4932b6e..0e103d057 100644 --- a/packages/0x.js/src/globals.d.ts +++ b/packages/0x.js/src/globals.d.ts @@ -41,19 +41,3 @@ declare module 'truffle-hdwallet-provider' { } export = HDWalletProvider; } - -// abi-decoder declarations -interface DecodedLogArg {} -interface DecodedLog { - name: string; - events: DecodedLogArg[]; -} -declare module 'abi-decoder' { - import * as Web3 from 'web3'; - const addABI: (abi: Web3.AbiDefinition) => void; - const decodeLogs: (logs: Web3.LogEntry[]) => DecodedLog[]; -} - -declare module 'web3/lib/solidity/coder' { - const decodeParams: (types: string[], data: string) => any[]; -} diff --git a/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts index 599c3a2b0..41e67e177 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -28,12 +28,9 @@ export { WithdrawalContractEventArgs, DepositContractEventArgs, ContractEventArgs, - ContractEventArg, Web3Provider, ZeroExConfig, EtherTokenEvents, - TransactionReceiptWithDecodedLogs, - LogWithDecodedArgs, MethodOpts, OrderTransactionOpts, TransactionOpts, @@ -47,4 +44,6 @@ export { OrderState, } from './types'; +export { ContractEventArg, LogWithDecodedArgs, TransactionReceiptWithDecodedLogs } from '@0xproject/types'; + export { TransactionReceipt } from '@0xproject/types'; diff --git a/packages/0x.js/src/order_watcher/order_state_watcher.ts b/packages/0x.js/src/order_watcher/order_state_watcher.ts index 12ac60960..576be00c8 100644 --- a/packages/0x.js/src/order_watcher/order_state_watcher.ts +++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts @@ -1,5 +1,6 @@ import { schemas } from '@0xproject/json-schemas'; -import { intervalUtils } from '@0xproject/utils'; +import { LogWithDecodedArgs } from '@0xproject/types'; +import { AbiDecoder, intervalUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; @@ -19,7 +20,6 @@ import { LogCancelContractEventArgs, LogEvent, LogFillContractEventArgs, - LogWithDecodedArgs, OnOrderStateChangeCallback, OrderState, OrderStateWatcherConfig, @@ -29,7 +29,6 @@ import { WithdrawalContractEventArgs, ZeroExError, } from '../types'; -import { AbiDecoder } from '../utils/abi_decoder'; import { assert } from '../utils/assert'; import { OrderStateUtils } from '../utils/order_state_utils'; import { utils } from '../utils/utils'; @@ -224,12 +223,12 @@ export class OrderStateWatcher { return; } const log = logIfExists as LogEvent; // At this moment we are sure that no error occured and log is defined. - const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop(log); - const isLogDecoded = !_.isUndefined((maybeDecodedLog as LogWithDecodedArgs<any>).event); + const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop<ContractEventArgs>(log); + const isLogDecoded = !_.isUndefined(((maybeDecodedLog as any) as LogWithDecodedArgs<ContractEventArgs>).event); if (!isLogDecoded) { return; // noop } - const decodedLog = maybeDecodedLog as LogWithDecodedArgs<ContractEventArgs>; + const decodedLog = (maybeDecodedLog as any) as LogWithDecodedArgs<ContractEventArgs>; let makerToken: string; let makerAddress: string; switch (decodedLog.event) { diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index 3c93910e9..a0deb91c9 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -1,4 +1,4 @@ -import { TransactionReceipt } from '@0xproject/types'; +import { ContractEventArg, LogWithDecodedArgs } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as Web3 from 'web3'; @@ -53,13 +53,6 @@ export interface DecodedLogEvent<ArgsType> { export type EventCallback<ArgsType> = (err: null | Error, log?: DecodedLogEvent<ArgsType>) => void; export type EventWatcherCallback = (err: null | Error, log?: LogEvent) => void; -export enum SolidityTypes { - Address = 'address', - Uint256 = 'uint256', - Uint8 = 'uint8', - Uint = 'uint', -} - export enum ExchangeContractErrCodes { ERROR_FILL_EXPIRED, // Order has already expired ERROR_FILL_NO_VALUE, // Order has already been fully filled or cancelled @@ -94,8 +87,6 @@ export enum ExchangeContractErrs { BatchOrdersMustHaveAtLeastOneItem = 'BATCH_ORDERS_MUST_HAVE_AT_LEAST_ONE_ITEM', } -export type RawLog = Web3.LogEntry; - export interface ContractEvent { logIndex: number; transactionIndex: number; @@ -163,7 +154,6 @@ export type EtherTokenContractEventArgs = | DepositContractEventArgs | WithdrawalContractEventArgs; export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs; -export type ContractEventArg = string | BigNumber; export interface Order { maker: string; @@ -267,11 +257,6 @@ export type SyncMethod = (...args: any[]) => any; */ export type Web3Provider = Web3.Provider; -export interface JSONRPCPayload { - params: any[]; - method: string; -} - /* * orderExpirationCheckingIntervalMs: How often to check for expired orders. Default: 50 * eventPollingIntervalMs: How often to poll the Ethereum node for new events. Defaults: 200 @@ -305,23 +290,6 @@ export interface ZeroExConfig { orderWatcherConfig?: OrderStateWatcherConfig; } -export enum AbiType { - Function = 'function', - Constructor = 'constructor', - Event = 'event', - Fallback = 'fallback', -} - -export interface DecodedLogArgs { - [argName: string]: ContractEventArg; -} - -export interface LogWithDecodedArgs<ArgsType> extends Web3.DecodedLogEntry<ArgsType> {} - -export interface TransactionReceiptWithDecodedLogs extends TransactionReceipt { - logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>; -} - export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken'; export interface Artifact { diff --git a/packages/0x.js/src/utils/utils.ts b/packages/0x.js/src/utils/utils.ts index 42cf5d956..74f2c5995 100644 --- a/packages/0x.js/src/utils/utils.ts +++ b/packages/0x.js/src/utils/utils.ts @@ -1,10 +1,11 @@ +import { SolidityTypes } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import BN = require('bn.js'); import * as ethABI from 'ethereumjs-abi'; import * as ethUtil from 'ethereumjs-util'; import * as _ from 'lodash'; -import { Order, SignedOrder, SolidityTypes } from '../types'; +import { Order, SignedOrder } from '../types'; export const utils = { /** diff --git a/packages/0x.js/test/0x.js_test.ts b/packages/0x.js/test/0x.js_test.ts index 927fe20be..5ebb68c8c 100644 --- a/packages/0x.js/test/0x.js_test.ts +++ b/packages/0x.js/test/0x.js_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import * as _ from 'lodash'; @@ -10,9 +10,8 @@ import { ApprovalContractEventArgs, LogWithDecodedArgs, Order, TokenEvents, Zero import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; import { TokenUtils } from './utils/token_utils'; -import { web3Factory } from './utils/web3_factory'; -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); chaiSetup.configure(); const expect = chai.expect; diff --git a/packages/0x.js/test/assert_test.ts b/packages/0x.js/test/assert_test.ts index 1f2820070..c4451742f 100644 --- a/packages/0x.js/test/assert_test.ts +++ b/packages/0x.js/test/assert_test.ts @@ -1,3 +1,4 @@ +import { web3Factory } from '@0xproject/dev-utils'; import * as chai from 'chai'; import 'mocha'; @@ -5,7 +6,6 @@ import { ZeroEx } from '../src'; import { assert } from '../src/utils/assert'; import { constants } from './utils/constants'; -import { web3Factory } from './utils/web3_factory'; const expect = chai.expect; diff --git a/packages/0x.js/test/ether_token_wrapper_test.ts b/packages/0x.js/test/ether_token_wrapper_test.ts index b810fc9f1..6069b42bf 100644 --- a/packages/0x.js/test/ether_token_wrapper_test.ts +++ b/packages/0x.js/test/ether_token_wrapper_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import 'mocha'; @@ -24,11 +24,10 @@ import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; import { reportNodeCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); // Since the address depositing/withdrawing ETH/WETH also needs to pay gas costs for the transaction, // a small amount of ETH will be used to pay this gas cost. We therefore check that the difference between diff --git a/packages/0x.js/test/event_watcher_test.ts b/packages/0x.js/test/event_watcher_test.ts index f92fb2b02..93ee9cd1c 100644 --- a/packages/0x.js/test/event_watcher_test.ts +++ b/packages/0x.js/test/event_watcher_test.ts @@ -1,3 +1,4 @@ +import { web3Factory } from '@0xproject/dev-utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import * as _ from 'lodash'; @@ -11,7 +12,6 @@ import { DoneCallback } from '../src/types'; import { chaiSetup } from './utils/chai_setup'; import { reportNodeCallbackErrors } from './utils/report_callback_errors'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; diff --git a/packages/0x.js/test/exchange_transfer_simulator_test.ts b/packages/0x.js/test/exchange_transfer_simulator_test.ts index 20b4a05ca..e85a1640f 100644 --- a/packages/0x.js/test/exchange_transfer_simulator_test.ts +++ b/packages/0x.js/test/exchange_transfer_simulator_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; @@ -8,11 +8,10 @@ import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simula import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); describe('ExchangeTransferSimulator', () => { const web3 = web3Factory.create(); diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts index 7e0ffd818..c15cd65a9 100644 --- a/packages/0x.js/test/exchange_wrapper_test.ts +++ b/packages/0x.js/test/exchange_wrapper_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import * as _ from 'lodash'; @@ -25,11 +25,10 @@ import { constants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; import { reportNodeCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777'; diff --git a/packages/0x.js/test/expiration_watcher_test.ts b/packages/0x.js/test/expiration_watcher_test.ts index 770615f88..b49dee8e5 100644 --- a/packages/0x.js/test/expiration_watcher_test.ts +++ b/packages/0x.js/test/expiration_watcher_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import * as _ from 'lodash'; @@ -13,15 +13,13 @@ import { constants } from '../src/utils/constants'; import { utils } from '../src/utils/utils'; import { chaiSetup } from './utils/chai_setup'; -import { constants as testConstants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; import { reportNoErrorCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(testConstants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); describe('ExpirationWatcher', () => { let web3: Web3; diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 2e9202fe2..9e2ad89e1 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import * as _ from 'lodash'; @@ -22,13 +22,12 @@ import { constants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; import { reportNodeCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; -import { web3Factory } from './utils/web3_factory'; const TIMEOUT_MS = 150; chaiSetup.configure(); const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); describe('OrderStateWatcher', () => { let web3: Web3; diff --git a/packages/0x.js/test/order_validation_test.ts b/packages/0x.js/test/order_validation_test.ts index be3e0590c..934e2e51f 100644 --- a/packages/0x.js/test/order_validation_test.ts +++ b/packages/0x.js/test/order_validation_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import * as Sinon from 'sinon'; @@ -13,11 +13,10 @@ import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; import { TokenUtils } from './utils/token_utils'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); describe('OrderValidation', () => { let web3: Web3; diff --git a/packages/0x.js/test/subscription_test.ts b/packages/0x.js/test/subscription_test.ts index f4c6f748f..f485bf84b 100644 --- a/packages/0x.js/test/subscription_test.ts +++ b/packages/0x.js/test/subscription_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import 'mocha'; @@ -11,10 +11,9 @@ import { DoneCallback } from '../src/types'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; import { assertNodeCallbackError } from './utils/report_callback_errors'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); describe('SubscriptionTest', () => { let web3: Web3; diff --git a/packages/0x.js/test/token_registry_wrapper_test.ts b/packages/0x.js/test/token_registry_wrapper_test.ts index 0a170db8f..fefb99b16 100644 --- a/packages/0x.js/test/token_registry_wrapper_test.ts +++ b/packages/0x.js/test/token_registry_wrapper_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { schemas, SchemaValidator } from '@0xproject/json-schemas'; import * as chai from 'chai'; import * as _ from 'lodash'; @@ -8,11 +8,10 @@ import { Token, ZeroEx } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7; diff --git a/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts b/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts index 15bd7a8ba..dc9ec2064 100644 --- a/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts +++ b/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts @@ -1,10 +1,10 @@ +import { web3Factory } from '@0xproject/dev-utils'; import * as chai from 'chai'; import { ZeroEx } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts index 4ba1f07c5..070d6ec47 100644 --- a/packages/0x.js/test/token_wrapper_test.ts +++ b/packages/0x.js/test/token_wrapper_test.ts @@ -1,4 +1,4 @@ -import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; @@ -22,11 +22,10 @@ import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; import { reportNodeCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; -import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); +const blockchainLifecycle = new BlockchainLifecycle(); describe('TokenWrapper', () => { let web3: Web3; diff --git a/packages/0x.js/test/utils/constants.ts b/packages/0x.js/test/utils/constants.ts index a9e665c25..cf030259c 100644 --- a/packages/0x.js/test/utils/constants.ts +++ b/packages/0x.js/test/utils/constants.ts @@ -1,11 +1,9 @@ export const constants = { NULL_ADDRESS: '0x0000000000000000000000000000000000000000', - RPC_URL: 'http://localhost:8545', ROPSTEN_NETWORK_ID: 3, KOVAN_NETWORK_ID: 42, TESTRPC_NETWORK_ID: 50, KOVAN_RPC_URL: 'https://kovan.infura.io/', ROPSTEN_RPC_URL: 'https://ropsten.infura.io/', ZRX_DECIMALS: 18, - GAS_ESTIMATE: 500000, }; diff --git a/packages/assert/tsconfig.json b/packages/assert/tsconfig.json index 88a467ccb..10354fa33 100644 --- a/packages/assert/tsconfig.json +++ b/packages/assert/tsconfig.json @@ -3,5 +3,10 @@ "compilerOptions": { "outDir": "lib" }, - "include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"] + "include": [ + "./src/**/*", + "./test/**/*", + "../../node_modules/web3-typescript-typings/index.d.ts", + "../../node_modules/chai-typescript-typings/index.d.ts" + ] } diff --git a/packages/chai-as-promised-typescript-typings/package.json b/packages/chai-as-promised-typescript-typings/package.json index 1d5cd4334..5c57a0e04 100644 --- a/packages/chai-as-promised-typescript-typings/package.json +++ b/packages/chai-as-promised-typescript-typings/package.json @@ -9,15 +9,13 @@ "url": "git+https://github.com/0xProject/0x.js.git" }, "author": "Fabio Berger", - "contributors": [ - "Leonid Logvinov <logvinov.leon@gmail.com>" - ], + "contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"], "license": "Apache-2.0", "bugs": { "url": "https://github.com/0xProject/0x.js/issues" }, "homepage": "https://github.com/0xProject/0x.js/packages/chai-as-promised-typescript-typings#readme", "dependencies": { - "chai-typescript-typings": "^0.0.0" + "chai-typescript-typings": "^0.0.2" } } diff --git a/packages/connect/package.json b/packages/connect/package.json index 9da25a35a..2dbd97dc4 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -2,20 +2,15 @@ "name": "@0xproject/connect", "version": "0.5.3", "description": "A javascript library for interacting with the standard relayer api", - "keywords": [ - "connect", - "0xproject", - "ethereum", - "tokens", - "exchange" - ], + "keywords": ["connect", "0xproject", "ethereum", "tokens", "exchange"], "main": "lib/src/index.js", "types": "lib/src/index.d.ts", "scripts": { "build": "tsc", "clean": "shx rm -rf _bundles lib test_temp", "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR", - "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json", + "upload_docs_json": + "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json", "copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures", "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'", "run_mocha": "mocha lib/test/**/*_test.js", diff --git a/packages/connect/tsconfig.json b/packages/connect/tsconfig.json index 3c150236e..fd9e604ad 100644 --- a/packages/connect/tsconfig.json +++ b/packages/connect/tsconfig.json @@ -6,6 +6,7 @@ "include": [ "./src/**/*", "./test/**/*", + "../../node_modules/web3-typescript-typings/index.d.ts", "../../node_modules/chai-as-promised-typescript-typings/index.d.ts", "../../node_modules/chai-typescript-typings/index.d.ts" ] diff --git a/packages/contracts/contracts/Exchange.sol b/packages/contracts/contracts/Exchange.sol index a402e7ca5..1da74deef 100644 --- a/packages/contracts/contracts/Exchange.sol +++ b/packages/contracts/contracts/Exchange.sol @@ -600,4 +600,3 @@ contract Exchange is SafeMath { return Token(token).allowance.gas(EXTERNAL_QUERY_GAS_LIMIT)(owner, TOKEN_TRANSFER_PROXY_CONTRACT); // Limit gas to prevent reentrancy } } - diff --git a/packages/contracts/globals.d.ts b/packages/contracts/globals.d.ts index 2e5827324..0e6586a4b 100644 --- a/packages/contracts/globals.d.ts +++ b/packages/contracts/globals.d.ts @@ -32,7 +32,3 @@ declare module 'ethereumjs-abi' { const soliditySHA3: (argTypes: string[], args: any[]) => Buffer; const methodID: (name: string, types: string[]) => Buffer; } - -// Truffle injects the following into the global scope -declare var artifacts: any; -declare var contract: any; diff --git a/packages/contracts/migrations/1_initial_migration.ts b/packages/contracts/migrations/1_initial_migration.ts deleted file mode 100644 index 8661ee218..000000000 --- a/packages/contracts/migrations/1_initial_migration.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Artifacts } from '../util/artifacts'; -const { Migrations } = new Artifacts(artifacts); - -module.exports = (deployer: any) => { - deployer.deploy(Migrations); -}; diff --git a/packages/contracts/migrations/2_deploy_independent_contracts.ts b/packages/contracts/migrations/2_deploy_independent_contracts.ts deleted file mode 100644 index ac1752347..000000000 --- a/packages/contracts/migrations/2_deploy_independent_contracts.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Artifacts } from '../util/artifacts'; -import { MultiSigConfigByNetwork } from '../util/types'; -const { MultiSigWalletWithTimeLock, TokenTransferProxy, EtherToken, TokenRegistry } = new Artifacts(artifacts); - -let multiSigConfigByNetwork: MultiSigConfigByNetwork; -try { - /* tslint:disable */ - const multiSigConfig = require('./config/multisig'); - multiSigConfigByNetwork = multiSigConfig.multiSig; - /* tslint:enable */ -} catch (e) { - multiSigConfigByNetwork = {}; -} - -module.exports = (deployer: any, network: string, accounts: string[]) => { - const defaultConfig = { - owners: [accounts[0], accounts[1]], - confirmationsRequired: 2, - secondsRequired: 0, - }; - const config = multiSigConfigByNetwork[network] || defaultConfig; - if (network !== 'live') { - deployer - .deploy(MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired) - .then(() => { - return deployer.deploy(TokenTransferProxy); - }) - .then(() => { - return deployer.deploy(TokenRegistry); - }) - .then(() => { - return deployer.deploy(EtherToken); - }); - } else { - deployer.deploy([ - [MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired], - TokenTransferProxy, - TokenRegistry, - ]); - } -}; diff --git a/packages/contracts/migrations/3_register_tokens.ts b/packages/contracts/migrations/3_register_tokens.ts deleted file mode 100644 index d5cf63f94..000000000 --- a/packages/contracts/migrations/3_register_tokens.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as Bluebird from 'bluebird'; -import * as _ from 'lodash'; - -import { Artifacts } from '../util/artifacts'; -import { constants } from '../util/constants'; -import { ContractInstance, Token } from '../util/types'; - -import { tokenInfo } from './config/token_info'; -const { DummyToken, EtherToken, ZRXToken, TokenRegistry } = new Artifacts(artifacts); - -module.exports = (deployer: any, network: string) => { - const tokens = network === 'live' ? tokenInfo.live : tokenInfo.development; - deployer - .then(() => { - return TokenRegistry.deployed(); - }) - .then((tokenRegistry: ContractInstance) => { - if (network !== 'live') { - const totalSupply = Math.pow(10, 18) * 1000000000; - return Bluebird.each( - tokens.map((token: Token) => DummyToken.new(token.name, token.symbol, token.decimals, totalSupply)), - _.noop, - ).then((dummyTokens: ContractInstance[]) => { - const weth = { - address: EtherToken.address, - name: 'Ether Token', - symbol: 'WETH', - url: '', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }; - return Bluebird.each( - dummyTokens - .map((tokenContract: ContractInstance, i: number) => { - const token = tokens[i]; - return tokenRegistry.addToken( - tokenContract.address, - token.name, - token.symbol, - token.decimals, - token.ipfsHash, - token.swarmHash, - ); - }) - .concat( - tokenRegistry.addToken( - weth.address, - weth.name, - weth.symbol, - weth.decimals, - weth.ipfsHash, - weth.swarmHash, - ), - ), - _.noop, - ); - }); - } else { - const zrx = { - address: ZRXToken.address, - name: '0x Protocol Token', - symbol: 'ZRX', - url: 'https://www.0xproject.com/', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }; - return Bluebird.each( - tokens - .map((token: Token) => { - return tokenRegistry.addToken( - token.address, - token.name, - token.symbol, - token.decimals, - token.ipfsHash, - token.swarmHash, - ); - }) - .concat( - tokenRegistry.addToken( - zrx.address, - zrx.name, - zrx.symbol, - zrx.decimals, - zrx.ipfsHash, - zrx.swarmHash, - ), - ), - _.noop, - ); - } - }); -}; diff --git a/packages/contracts/migrations/4_configure_proxy.ts b/packages/contracts/migrations/4_configure_proxy.ts deleted file mode 100644 index ff3b844d6..000000000 --- a/packages/contracts/migrations/4_configure_proxy.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Artifacts } from '../util/artifacts'; -import { ContractInstance } from '../util/types'; -const { TokenTransferProxy, Exchange, TokenRegistry } = new Artifacts(artifacts); - -let tokenTransferProxy: ContractInstance; -module.exports = (deployer: any) => { - deployer - .then(async () => { - return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()]); - }) - .then((instances: ContractInstance[]) => { - let tokenRegistry: ContractInstance; - [tokenTransferProxy, tokenRegistry] = instances; - return tokenRegistry.getTokenAddressBySymbol('ZRX'); - }) - .then((ptAddress: string) => { - return deployer.deploy(Exchange, ptAddress, tokenTransferProxy.address); - }) - .then(() => { - return tokenTransferProxy.addAuthorizedAddress(Exchange.address); - }); -}; diff --git a/packages/contracts/migrations/5_transfer_ownership.ts b/packages/contracts/migrations/5_transfer_ownership.ts deleted file mode 100644 index a27801de3..000000000 --- a/packages/contracts/migrations/5_transfer_ownership.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Artifacts } from '../util/artifacts'; -import { ContractInstance } from '../util/types'; -const { TokenTransferProxy, MultiSigWalletWithTimeLock, TokenRegistry } = new Artifacts(artifacts); - -let tokenRegistry: ContractInstance; -module.exports = (deployer: any, network: string) => { - if (network !== 'development') { - deployer.then(async () => { - return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()]) - .then((instances: ContractInstance[]) => { - let tokenTransferProxy: ContractInstance; - [tokenTransferProxy, tokenRegistry] = instances; - return tokenTransferProxy.transferOwnership(MultiSigWalletWithTimeLock.address); - }) - .then(() => { - return tokenRegistry.transferOwnership(MultiSigWalletWithTimeLock.address); - }); - }); - } -}; diff --git a/packages/contracts/migrations/config/multisig_sample.ts b/packages/contracts/migrations/config/multisig_sample.ts deleted file mode 100644 index 97cdc2eae..000000000 --- a/packages/contracts/migrations/config/multisig_sample.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { MultiSigConfigByNetwork } from '../../util/types'; - -// Make a copy of this file named `multisig.js` and input custom params as needed -export const multiSig: MultiSigConfigByNetwork = { - kovan: { - owners: [], - confirmationsRequired: 0, - secondsRequired: 0, - }, -}; diff --git a/packages/contracts/migrations/config/token_info.ts b/packages/contracts/migrations/config/token_info.ts deleted file mode 100644 index 6ae67175e..000000000 --- a/packages/contracts/migrations/config/token_info.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { constants } from '../../util/constants'; -import { TokenInfoByNetwork } from '../../util/types'; - -export const tokenInfo: TokenInfoByNetwork = { - development: [ - { - name: '0x Protocol Token', - symbol: 'ZRX', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - name: 'Augur Reputation Token', - symbol: 'REP', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - name: 'Digix DAO Token', - symbol: 'DGD', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - name: 'Golem Network Token', - symbol: 'GNT', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - name: 'MakerDAO', - symbol: 'MKR', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - name: 'Melon Token', - symbol: 'MLN', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - ], - live: [ - { - address: '0xecf8f87f810ecf450940c9f60066b4a7a501d6a7', - name: 'ETH Wrapper Token', - symbol: 'WETH', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - address: '0x48c80f1f4d53d5951e5d5438b54cba84f29f32a5', - name: 'Augur Reputation Token', - symbol: 'REP', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - address: '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a', - name: 'Digix DAO Token', - symbol: 'DGD', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - address: '0xa74476443119a942de498590fe1f2454d7d4ac0d', - name: 'Golem Network Token', - symbol: 'GNT', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - address: '0xc66ea802717bfb9833400264dd12c2bceaa34a6d', - name: 'MakerDAO', - symbol: 'MKR', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - { - address: '0xbeb9ef514a379b997e0798fdcc901ee474b6d9a1', - name: 'Melon Token', - symbol: 'MLN', - decimals: 18, - ipfsHash: constants.NULL_BYTES, - swarmHash: constants.NULL_BYTES, - }, - ], -}; diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 3a140b23e..d2f4df0b4 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -8,9 +8,13 @@ "test": "test" }, "scripts": { - "build": "rm -rf ./lib; copyfiles ./build/**/* ./deploy/solc/solc_bin/* ./deploy/test/fixtures/contracts/**/* ./deploy/test/fixtures/contracts/* ./lib; tsc;", - "test": "npm run build; truffle test", - "compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846", + "prebuild": "run-s clean copy_artifacts", + "copy_artifacts": "copyfiles './build/**/*' './deploy/solc/solc_bin/*' './deploy/test/fixtures/contracts/**/*' './deploy/test/fixtures/contracts/*' ./lib", + "build": "tsc", + "test": "run-s compile build run_mocha", + "run_mocha": "mocha 'lib/test/**/*.js' --timeout 10000 --bail --exit", + "compile:comment": + "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846", "compile": "node ../deployer/lib/src/cli.js compile", "clean": "rm -rf ./lib", "migrate": "node ../deployer/lib/src/cli.js migrate", @@ -44,11 +48,11 @@ "copyfiles": "^1.2.0", "dirty-chai": "^2.0.1", "mocha": "^4.0.1", + "npm-run-all": "^4.1.2", "solc": "^0.4.18", - "truffle": "^4.0.1", "tslint": "5.8.0", "types-bn": "^0.0.1", - "types-ethereumjs-util": "0xProject/types-ethereumjs-util", + "types-ethereumjs-util": "0xproject/types-ethereumjs-util", "typescript": "~2.6.1", "web3-typescript-typings": "^0.9.7", "yargs": "^10.0.3" diff --git a/packages/contracts/test/ts/ether_token.ts b/packages/contracts/test/ether_token.ts index f807cdaa3..4c70534ee 100644 --- a/packages/contracts/test/ts/ether_token.ts +++ b/packages/contracts/test/ether_token.ts @@ -1,46 +1,46 @@ import { ZeroEx, ZeroExError } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber, promisify } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; -import Web3 = require('web3'); -import { Artifacts } from '../../util/artifacts'; -import { constants } from '../../util/constants'; +import { constants } from '../util/constants'; +import { ContractName } from '../util/types'; import { chaiSetup } from './utils/chai_setup'; - -const { EtherToken } = new Artifacts(artifacts); +import { deployer } from './utils/deployer'; chaiSetup.configure(); const expect = chai.expect; +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); -// In order to benefit from type-safety, we re-assign the global web3 instance injected by Truffle -// with type `any` to a variable of type `Web3`. -const web3: Web3 = (global as any).web3; - -contract('EtherToken', (accounts: string[]) => { - const account = accounts[0]; +describe('EtherToken', () => { + let account: string; const gasPrice = ZeroEx.toBaseUnitAmount(new BigNumber(20), 9); let zeroEx: ZeroEx; let etherTokenAddress: string; - before(async () => { - etherTokenAddress = EtherToken.address; + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + account = accounts[0]; + + const etherToken = await deployer.deployAsync(ContractName.EtherToken); + etherTokenAddress = etherToken.address; zeroEx = new ZeroEx(web3.currentProvider, { gasPrice, networkId: constants.TESTRPC_NETWORK_ID, }); }); - - const sendTransactionAsync = promisify<string>(web3.eth.sendTransaction); - const getEthBalanceAsync = async (owner: string) => { - const balanceStr = await promisify<string>(web3.eth.getBalance)(owner); - const balance = new BigNumber(balanceStr); - return balance; - }; - + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); describe('deposit', () => { it('should throw if caller attempts to deposit more Ether than caller balance', async () => { - const initEthBalance = await getEthBalanceAsync(account); + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); const ethToDeposit = initEthBalance.plus(1); return expect(zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account)).to.be.rejectedWith( @@ -49,7 +49,7 @@ contract('EtherToken', (accounts: string[]) => { }); it('should convert deposited Ether to wrapped Ether tokens', async () => { - const initEthBalance = await getEthBalanceAsync(account); + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account); const ethToDeposit = new BigNumber(web3.toWei(1, 'ether')); @@ -58,7 +58,7 @@ contract('EtherToken', (accounts: string[]) => { const receipt = await zeroEx.awaitTransactionMinedAsync(txHash); const ethSpentOnGas = gasPrice.times(receipt.gasUsed); - const finalEthBalance = await getEthBalanceAsync(account); + const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account); expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas))); @@ -77,8 +77,10 @@ contract('EtherToken', (accounts: string[]) => { }); it('should convert ether tokens to ether with sufficient balance', async () => { + const ethToDeposit = new BigNumber(web3.toWei(1, 'ether')); + await zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account); const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account); - const initEthBalance = await getEthBalanceAsync(account); + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); const ethTokensToWithdraw = initEthTokenBalance; expect(ethTokensToWithdraw).to.not.be.bignumber.equal(0); const txHash = await zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account, { @@ -87,7 +89,7 @@ contract('EtherToken', (accounts: string[]) => { const receipt = await zeroEx.awaitTransactionMinedAsync(txHash); const ethSpentOnGas = gasPrice.times(receipt.gasUsed); - const finalEthBalance = await getEthBalanceAsync(account); + const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account); expect(finalEthBalance).to.be.bignumber.equal( @@ -99,12 +101,12 @@ contract('EtherToken', (accounts: string[]) => { describe('fallback', () => { it('should convert sent ether to ether tokens', async () => { - const initEthBalance = await getEthBalanceAsync(account); + const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account); const ethToDeposit = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); - const txHash = await sendTransactionAsync({ + const txHash = await web3Wrapper.sendTransactionAsync({ from: account, to: etherTokenAddress, value: ethToDeposit, @@ -114,7 +116,7 @@ contract('EtherToken', (accounts: string[]) => { const receipt = await zeroEx.awaitTransactionMinedAsync(txHash); const ethSpentOnGas = gasPrice.times(receipt.gasUsed); - const finalEthBalance = await getEthBalanceAsync(account); + const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account); expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas))); diff --git a/packages/contracts/test/ts/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 770ef0c43..e9182dd1b 100644 --- a/packages/contracts/test/ts/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -1,41 +1,47 @@ -import { ZeroEx } from '0x.js'; +import { + LogCancelContractEventArgs, + LogErrorContractEventArgs, + LogFillContractEventArgs, + LogWithDecodedArgs, + TransactionReceiptWithDecodedLogs, + ZeroEx, +} from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); import * as Web3 from 'web3'; -import { Artifacts } from '../../../util/artifacts'; -import { Balances } from '../../../util/balances'; -import { constants } from '../../../util/constants'; -import { crypto } from '../../../util/crypto'; -import { ExchangeWrapper } from '../../../util/exchange_wrapper'; -import { Order } from '../../../util/order'; -import { OrderFactory } from '../../../util/order_factory'; -import { BalancesByOwner, ContractInstance, ExchangeContractErrs } from '../../../util/types'; +import { Balances } from '../../util/balances'; +import { constants } from '../../util/constants'; +import { crypto } from '../../util/crypto'; +import { ExchangeWrapper } from '../../util/exchange_wrapper'; +import { Order } from '../../util/order'; +import { OrderFactory } from '../../util/order_factory'; +import { BalancesByOwner, ContractName, ExchangeContractErrs } from '../../util/types'; import { chaiSetup } from '../utils/chai_setup'; +import { deployer } from '../utils/deployer'; chaiSetup.configure(); const expect = chai.expect; -const { Exchange, TokenTransferProxy, DummyToken, TokenRegistry, MaliciousToken } = new Artifacts(artifacts); - -// In order to benefit from type-safety, we re-assign the global web3 instance injected by Truffle -// with type `any` to a variable of type `Web3`. -const web3: Web3 = (global as any).web3; - -contract('Exchange', (accounts: string[]) => { - const maker = accounts[0]; - const tokenOwner = accounts[0]; - const taker = accounts[1] || accounts[accounts.length - 1]; - const feeRecipient = accounts[2] || accounts[accounts.length - 1]; - +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); + +describe('Exchange', () => { + let maker: string; + let tokenOwner: string; + let taker: string; + let feeRecipient: string; const INITIAL_BALANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18); const INITIAL_ALLOWANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18); - let rep: ContractInstance; - let dgd: ContractInstance; - let zrx: ContractInstance; - let exchange: ContractInstance; - let tokenRegistry: ContractInstance; + let rep: Web3.ContractInstance; + let dgd: Web3.ContractInstance; + let zrx: Web3.ContractInstance; + let exchange: Web3.ContractInstance; + let tokenTransferProxy: Web3.ContractInstance; let order: Order; let balances: BalancesByOwner; @@ -46,66 +52,69 @@ contract('Exchange', (accounts: string[]) => { let zeroEx: ZeroEx; before(async () => { - [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]); - exWrapper = new ExchangeWrapper(exchange); + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + maker = accounts[0]; + [tokenOwner, taker, feeRecipient] = accounts; + [rep, dgd, zrx] = await Promise.all([ + deployer.deployAsync(ContractName.DummyToken), + deployer.deployAsync(ContractName.DummyToken), + deployer.deployAsync(ContractName.DummyToken), + ]); + tokenTransferProxy = await deployer.deployAsync(ContractName.TokenTransferProxy); + exchange = await deployer.deployAsync(ContractName.Exchange, [zrx.address, tokenTransferProxy.address]); + await tokenTransferProxy.addAuthorizedAddress(exchange.address, { from: accounts[0] }); zeroEx = new ZeroEx(web3.currentProvider, { exchangeContractAddress: exchange.address, networkId: constants.TESTRPC_NETWORK_ID, }); - - const [repAddress, dgdAddress, zrxAddress] = await Promise.all([ - tokenRegistry.getTokenAddressBySymbol('REP'), - tokenRegistry.getTokenAddressBySymbol('DGD'), - tokenRegistry.getTokenAddressBySymbol('ZRX'), - ]); + exWrapper = new ExchangeWrapper(exchange, zeroEx); const defaultOrderParams = { - exchangeContractAddress: Exchange.address, + exchangeContractAddress: exchange.address, maker, feeRecipient, - makerToken: repAddress, - takerToken: dgdAddress, + makerToken: rep.address, + takerToken: dgd.address, makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18), takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18), makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18), takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18), }; - orderFactory = new OrderFactory(defaultOrderParams); - - [rep, dgd, zrx] = await Promise.all([ - DummyToken.at(repAddress), - DummyToken.at(dgdAddress), - DummyToken.at(zrxAddress), - ]); + orderFactory = new OrderFactory(web3Wrapper, defaultOrderParams); dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]); await Promise.all([ - rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + rep.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: maker, }), - rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + rep.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker, }), rep.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }), rep.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }), - dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + dgd.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: maker, }), - dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + dgd.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker, }), dgd.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }), dgd.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }), - zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + zrx.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: maker, }), - zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + zrx.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker, }), zrx.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }), zrx.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }), ]); }); - + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); describe('internal functions', () => { it('should include transferViaTokenTransferProxy', () => { expect(exchange.transferViaTokenTransferProxy).to.be.undefined(); @@ -136,9 +145,8 @@ contract('Exchange', (accounts: string[]) => { takerTokenAmount: new BigNumber(3), }); - const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0); const fillTakerTokenAmount1 = new BigNumber(2); @@ -146,9 +154,8 @@ contract('Exchange', (accounts: string[]) => { fillTakerTokenAmount: fillTakerTokenAmount1, }); - const filledTakerTokenAmountAfter1 = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountAfter1 = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountAfter1).to.be.bignumber.equal(fillTakerTokenAmount1); const fillTakerTokenAmount2 = new BigNumber(1); @@ -156,9 +163,8 @@ contract('Exchange', (accounts: string[]) => { fillTakerTokenAmount: fillTakerTokenAmount2, }); - const filledTakerTokenAmountAfter2 = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountAfter2 = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountAfter2).to.be.bignumber.equal(filledTakerTokenAmountAfter1); }); @@ -168,17 +174,15 @@ contract('Exchange', (accounts: string[]) => { takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18), }); - const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0); const fillTakerTokenAmount = order.params.takerTokenAmount.div(2); await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount }); - const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount); const newBalances = await dmyBalances.getAsync(); @@ -221,17 +225,15 @@ contract('Exchange', (accounts: string[]) => { takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18), }); - const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0); const fillTakerTokenAmount = order.params.takerTokenAmount.div(2); await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount }); - const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount); const newBalances = await dmyBalances.getAsync(); @@ -274,17 +276,15 @@ contract('Exchange', (accounts: string[]) => { takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18), }); - const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0); const fillTakerTokenAmount = order.params.takerTokenAmount.div(2); await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount }); - const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount); const newBalances = await dmyBalances.getAsync(); @@ -328,17 +328,15 @@ contract('Exchange', (accounts: string[]) => { takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18), }); - const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0); const fillTakerTokenAmount = order.params.takerTokenAmount.div(2); await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount }); - const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync( - order.params.orderHashHex, - ); + const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(order.params + .orderHashHex as string); const expectedFillAmountTAfter = fillTakerTokenAmount.add(filledTakerTokenAmountBefore); expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(expectedFillAmountTAfter); @@ -383,8 +381,8 @@ contract('Exchange', (accounts: string[]) => { const res = await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount: order.params.takerTokenAmount, }); - - expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal( + const log = res.logs[0] as LogWithDecodedArgs<LogFillContractEventArgs>; + expect(log.args.filledTakerTokenAmount).to.be.bignumber.equal( order.params.takerTokenAmount.minus(fillTakerTokenAmount), ); const newBalances = await dmyBalances.getAsync(); @@ -419,7 +417,7 @@ contract('Exchange', (accounts: string[]) => { }); expect(res.logs).to.have.length(1); - const logArgs = res.logs[0].args; + const logArgs = (res.logs[0] as LogWithDecodedArgs<LogFillContractEventArgs>).args; const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor); const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor); const expectedFeeMPaid = order.params.makerFee.div(divisor); @@ -450,7 +448,7 @@ contract('Exchange', (accounts: string[]) => { }); expect(res.logs).to.have.length(1); - const logArgs = res.logs[0].args; + const logArgs = (res.logs[0] as LogWithDecodedArgs<LogFillContractEventArgs>).args; const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor); const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor); const expectedFeeMPaid = new BigNumber(0); @@ -567,9 +565,9 @@ contract('Exchange', (accounts: string[]) => { it('should not change balances if maker allowances are too low to fill order and \ shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - await rep.approve(TokenTransferProxy.address, 0, { from: maker }); + await rep.approve(tokenTransferProxy.address, 0, { from: maker }); await exWrapper.fillOrderAsync(order, taker); - await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + await rep.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: maker, }); @@ -579,22 +577,22 @@ contract('Exchange', (accounts: string[]) => { it('should throw if maker allowances are too low to fill order and \ shouldThrowOnInsufficientBalanceOrAllowance = true', async () => { - await rep.approve(TokenTransferProxy.address, 0, { from: maker }); + await rep.approve(tokenTransferProxy.address, 0, { from: maker }); expect( exWrapper.fillOrderAsync(order, taker, { shouldThrowOnInsufficientBalanceOrAllowance: true, }), ).to.be.rejectedWith(constants.REVERT); - await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + await rep.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: maker, }); }); it('should not change balances if taker allowances are too low to fill order and \ shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - await dgd.approve(TokenTransferProxy.address, 0, { from: taker }); + await dgd.approve(tokenTransferProxy.address, 0, { from: taker }); await exWrapper.fillOrderAsync(order, taker); - await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + await dgd.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker, }); @@ -604,13 +602,13 @@ contract('Exchange', (accounts: string[]) => { it('should throw if taker allowances are too low to fill order and \ shouldThrowOnInsufficientBalanceOrAllowance = true', async () => { - await dgd.approve(TokenTransferProxy.address, 0, { from: taker }); + await dgd.approve(tokenTransferProxy.address, 0, { from: taker }); expect( exWrapper.fillOrderAsync(order, taker, { shouldThrowOnInsufficientBalanceOrAllowance: true, }), ).to.be.rejectedWith(constants.REVERT); - await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { + await dgd.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker, }); }); @@ -630,7 +628,7 @@ contract('Exchange', (accounts: string[]) => { it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker allowance, \ and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const makerZRXAllowance = await zrx.allowance(maker, TokenTransferProxy.address); + const makerZRXAllowance = await zrx.allowance(maker, tokenTransferProxy.address); order = await orderFactory.newSignedOrderAsync({ makerToken: zrx.address, makerTokenAmount: new BigNumber(makerZRXAllowance), @@ -656,7 +654,7 @@ contract('Exchange', (accounts: string[]) => { it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker allowance, \ and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const takerZRXAllowance = await zrx.allowance(taker, TokenTransferProxy.address); + const takerZRXAllowance = await zrx.allowance(taker, tokenTransferProxy.address); order = await orderFactory.newSignedOrderAsync({ takerToken: zrx.address, takerTokenAmount: new BigNumber(takerZRXAllowance), @@ -669,8 +667,8 @@ contract('Exchange', (accounts: string[]) => { it('should throw if getBalance or getAllowance attempts to change state and \ shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const maliciousToken = await MaliciousToken.new(); - await maliciousToken.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker }); + const maliciousToken = await deployer.deployAsync(ContractName.MaliciousToken); + await maliciousToken.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker }); order = await orderFactory.newSignedOrderAsync({ takerToken: maliciousToken.address, @@ -680,7 +678,7 @@ contract('Exchange', (accounts: string[]) => { exWrapper.fillOrderAsync(order, taker, { shouldThrowOnInsufficientBalanceOrAllowance: false, }), - ).to.be.rejectedWith(constants.REVERT); + ).to.be.rejectedWith(constants.INVALID_OPCODE); }); it('should not change balances if an order is expired', async () => { @@ -700,16 +698,19 @@ contract('Exchange', (accounts: string[]) => { const res = await exWrapper.fillOrderAsync(order, taker); expect(res.logs).to.have.length(1); - const errCode = res.logs[0].args.errorId.toNumber(); + const log = res.logs[0] as LogWithDecodedArgs<LogErrorContractEventArgs>; + const errCode = log.args.errorId.toNumber(); expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED); }); it('should log an error event if no value is filled', async () => { + order = await orderFactory.newSignedOrderAsync({}); await exWrapper.fillOrderAsync(order, taker); const res = await exWrapper.fillOrderAsync(order, taker); expect(res.logs).to.have.length(1); - const errCode = res.logs[0].args.errorId.toNumber(); + const log = res.logs[0] as LogWithDecodedArgs<LogErrorContractEventArgs>; + const errCode = log.args.errorId.toNumber(); expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED); }); }); @@ -769,7 +770,8 @@ contract('Exchange', (accounts: string[]) => { const res = await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount: order.params.takerTokenAmount, }); - expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal( + const log = res.logs[0] as LogWithDecodedArgs<LogFillContractEventArgs>; + expect(log.args.filledTakerTokenAmount).to.be.bignumber.equal( order.params.takerTokenAmount.minus(cancelTakerTokenAmount), ); @@ -813,7 +815,8 @@ contract('Exchange', (accounts: string[]) => { }); expect(res.logs).to.have.length(1); - const logArgs = res.logs[0].args; + const log = res.logs[0] as LogWithDecodedArgs<LogCancelContractEventArgs>; + const logArgs = log.args; const expectedCancelledMakerTokenAmount = order.params.makerTokenAmount.div(divisor); const expectedCancelledTakerTokenAmount = order.params.takerTokenAmount.div(divisor); const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]); @@ -834,7 +837,8 @@ contract('Exchange', (accounts: string[]) => { const res = await exWrapper.cancelOrderAsync(order, maker); expect(res.logs).to.have.length(1); - const errCode = res.logs[0].args.errorId.toNumber(); + const log = res.logs[0] as LogWithDecodedArgs<LogErrorContractEventArgs>; + const errCode = log.args.errorId.toNumber(); expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED); }); @@ -845,7 +849,8 @@ contract('Exchange', (accounts: string[]) => { const res = await exWrapper.cancelOrderAsync(order, maker); expect(res.logs).to.have.length(1); - const errCode = res.logs[0].args.errorId.toNumber(); + const log = res.logs[0] as LogWithDecodedArgs<LogErrorContractEventArgs>; + const errCode = log.args.errorId.toNumber(); expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED); }); }); diff --git a/packages/contracts/test/ts/exchange/helpers.ts b/packages/contracts/test/exchange/helpers.ts index 95f68e419..5efce41a4 100644 --- a/packages/contracts/test/ts/exchange/helpers.ts +++ b/packages/contracts/test/exchange/helpers.ts @@ -1,52 +1,68 @@ import { ZeroEx } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); -import { Artifacts } from '../../../util/artifacts'; -import { ExchangeWrapper } from '../../../util/exchange_wrapper'; -import { Order } from '../../../util/order'; -import { OrderFactory } from '../../../util/order_factory'; +import { constants } from '../../util/constants'; +import { ExchangeWrapper } from '../../util/exchange_wrapper'; +import { Order } from '../../util/order'; +import { OrderFactory } from '../../util/order_factory'; +import { ContractName } from '../../util/types'; import { chaiSetup } from '../utils/chai_setup'; +import { deployer } from '../utils/deployer'; chaiSetup.configure(); const expect = chai.expect; -const { Exchange, TokenRegistry } = new Artifacts(artifacts); +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); -contract('Exchange', (accounts: string[]) => { - const maker = accounts[0]; - const feeRecipient = accounts[1] || accounts[accounts.length - 1]; +describe('Exchange', () => { + let maker: string; + let feeRecipient: string; let order: Order; let exchangeWrapper: ExchangeWrapper; let orderFactory: OrderFactory; before(async () => { - const [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]); - exchangeWrapper = new ExchangeWrapper(exchange); - const [repAddress, dgdAddress] = await Promise.all([ - tokenRegistry.getTokenAddressBySymbol('REP'), - tokenRegistry.getTokenAddressBySymbol('DGD'), + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + [maker, feeRecipient] = accounts; + const tokenRegistry = await deployer.deployAsync(ContractName.TokenRegistry); + const tokenTransferProxy = await deployer.deployAsync(ContractName.TokenTransferProxy); + const [rep, dgd, zrx] = await Promise.all([ + deployer.deployAsync(ContractName.DummyToken), + deployer.deployAsync(ContractName.DummyToken), + deployer.deployAsync(ContractName.DummyToken), ]); + const exchange = await deployer.deployAsync(ContractName.Exchange, [zrx.address, tokenTransferProxy.address]); + await tokenTransferProxy.addAuthorizedAddress(exchange.address, { from: accounts[0] }); + const zeroEx = new ZeroEx(web3.currentProvider, { networkId: constants.TESTRPC_NETWORK_ID }); + exchangeWrapper = new ExchangeWrapper(exchange, zeroEx); const defaultOrderParams = { - exchangeContractAddress: Exchange.address, + exchangeContractAddress: exchange.address, maker, feeRecipient, - makerToken: repAddress, - takerToken: dgdAddress, + makerToken: rep.address, + takerToken: dgd.address, makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18), takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18), makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18), takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18), }; - orderFactory = new OrderFactory(defaultOrderParams); + orderFactory = new OrderFactory(web3Wrapper, defaultOrderParams); + order = await orderFactory.newSignedOrderAsync(); }); beforeEach(async () => { - order = await orderFactory.newSignedOrderAsync(); + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); }); - describe('getOrderHash', () => { it('should output the correct orderHash', async () => { const orderHashHex = await exchangeWrapper.getOrderHashAsync(order); diff --git a/packages/contracts/test/ts/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index e69e08bcf..acdf481a9 100644 --- a/packages/contracts/test/ts/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -1,35 +1,41 @@ import { ZeroEx } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import * as _ from 'lodash'; - -import { Artifacts } from '../../../util/artifacts'; -import { Balances } from '../../../util/balances'; -import { constants } from '../../../util/constants'; -import { ExchangeWrapper } from '../../../util/exchange_wrapper'; -import { Order } from '../../../util/order'; -import { OrderFactory } from '../../../util/order_factory'; -import { BalancesByOwner, ContractInstance } from '../../../util/types'; +import * as Web3 from 'web3'; + +import { Balances } from '../../util/balances'; +import { constants } from '../../util/constants'; +import { ExchangeWrapper } from '../../util/exchange_wrapper'; +import { Order } from '../../util/order'; +import { OrderFactory } from '../../util/order_factory'; +import { BalancesByOwner, ContractName } from '../../util/types'; import { chaiSetup } from '../utils/chai_setup'; +import { deployer } from '../utils/deployer'; chaiSetup.configure(); const expect = chai.expect; -const { Exchange, TokenTransferProxy, DummyToken, TokenRegistry } = new Artifacts(artifacts); +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); -contract('Exchange', (accounts: string[]) => { - const maker = accounts[0]; - const tokenOwner = accounts[0]; - const taker = accounts[1] || accounts[accounts.length - 1]; - const feeRecipient = accounts[2] || accounts[accounts.length - 1]; +describe('Exchange', () => { + let maker: string; + let tokenOwner: string; + let taker: string; + let feeRecipient: string; const INIT_BAL = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18); const INIT_ALLOW = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18); - let rep: ContractInstance; - let dgd: ContractInstance; - let zrx: ContractInstance; - let exchange: ContractInstance; - let tokenRegistry: ContractInstance; + let rep: Web3.ContractInstance; + let dgd: Web3.ContractInstance; + let zrx: Web3.ContractInstance; + let exchange: Web3.ContractInstance; + let tokenRegistry: Web3.ContractInstance; + let tokenTransferProxy: Web3.ContractInstance; let balances: BalancesByOwner; @@ -38,49 +44,56 @@ contract('Exchange', (accounts: string[]) => { let orderFactory: OrderFactory; before(async () => { - [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]); - exWrapper = new ExchangeWrapper(exchange); - const [repAddress, dgdAddress, zrxAddress] = await Promise.all([ - tokenRegistry.getTokenAddressBySymbol('REP'), - tokenRegistry.getTokenAddressBySymbol('DGD'), - tokenRegistry.getTokenAddressBySymbol('ZRX'), + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + tokenOwner = accounts[0]; + [maker, taker, feeRecipient] = accounts; + [rep, dgd, zrx] = await Promise.all([ + deployer.deployAsync(ContractName.DummyToken), + deployer.deployAsync(ContractName.DummyToken), + deployer.deployAsync(ContractName.DummyToken), ]); + tokenRegistry = await deployer.deployAsync(ContractName.TokenRegistry); + tokenTransferProxy = await deployer.deployAsync(ContractName.TokenTransferProxy); + exchange = await deployer.deployAsync(ContractName.Exchange, [zrx.address, tokenTransferProxy.address]); + await tokenTransferProxy.addAuthorizedAddress(exchange.address, { from: accounts[0] }); + const zeroEx = new ZeroEx(web3.currentProvider, { networkId: constants.TESTRPC_NETWORK_ID }); + exWrapper = new ExchangeWrapper(exchange, zeroEx); const defaultOrderParams = { - exchangeContractAddress: Exchange.address, + exchangeContractAddress: exchange.address, maker, feeRecipient, - makerToken: repAddress, - takerToken: dgdAddress, + makerToken: rep.address, + takerToken: dgd.address, makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18), takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18), makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18), takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18), }; - orderFactory = new OrderFactory(defaultOrderParams); - [rep, dgd, zrx] = await Promise.all([ - DummyToken.at(repAddress), - DummyToken.at(dgdAddress), - DummyToken.at(zrxAddress), - ]); + orderFactory = new OrderFactory(web3Wrapper, defaultOrderParams); dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]); await Promise.all([ - rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }), - rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }), + rep.approve(tokenTransferProxy.address, INIT_ALLOW, { from: maker }), + rep.approve(tokenTransferProxy.address, INIT_ALLOW, { from: taker }), rep.setBalance(maker, INIT_BAL, { from: tokenOwner }), rep.setBalance(taker, INIT_BAL, { from: tokenOwner }), - dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }), - dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }), + dgd.approve(tokenTransferProxy.address, INIT_ALLOW, { from: maker }), + dgd.approve(tokenTransferProxy.address, INIT_ALLOW, { from: taker }), dgd.setBalance(maker, INIT_BAL, { from: tokenOwner }), dgd.setBalance(taker, INIT_BAL, { from: tokenOwner }), - zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }), - zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }), + zrx.approve(tokenTransferProxy.address, INIT_ALLOW, { from: maker }), + zrx.approve(tokenTransferProxy.address, INIT_ALLOW, { from: taker }), zrx.setBalance(maker, INIT_BAL, { from: tokenOwner }), zrx.setBalance(taker, INIT_BAL, { from: tokenOwner }), ]); }); - + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); describe('fillOrKillOrder', () => { beforeEach(async () => { balances = await dmyBalances.getAsync(); diff --git a/packages/contracts/test/multi_sig_with_time_lock.ts b/packages/contracts/test/multi_sig_with_time_lock.ts new file mode 100644 index 000000000..bd64be1ba --- /dev/null +++ b/packages/contracts/test/multi_sig_with_time_lock.ts @@ -0,0 +1,191 @@ +import { LogWithDecodedArgs, ZeroEx } from '0x.js'; +import { BlockchainLifecycle, RPC, web3Factory } from '@0xproject/dev-utils'; +import { AbiDecoder, BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as chai from 'chai'; +import * as Web3 from 'web3'; + +import * as multiSigWalletJSON from '../../build/contracts/MultiSigWalletWithTimeLock.json'; +import { artifacts } from '../util/artifacts'; +import { constants } from '../util/constants'; +import { MultiSigWrapper } from '../util/multi_sig_wrapper'; +import { ContractName, SubmissionContractEventArgs } from '../util/types'; + +import { chaiSetup } from './utils/chai_setup'; +import { deployer } from './utils/deployer'; + +const MULTI_SIG_ABI = artifacts.MultiSigWalletWithTimeLockArtifact.networks[constants.TESTRPC_NETWORK_ID].abi; +chaiSetup.configure(); +const expect = chai.expect; + +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); +const zeroEx = new ZeroEx(web3.currentProvider, { networkId: constants.TESTRPC_NETWORK_ID }); +const abiDecoder = new AbiDecoder([MULTI_SIG_ABI]); + +describe('MultiSigWalletWithTimeLock', () => { + let owners: string[]; + before(async () => { + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + owners = [accounts[0], accounts[1]]; + }); + const SIGNATURES_REQUIRED = 2; + const SECONDS_TIME_LOCKED = 10000; + + let multiSig: Web3.ContractInstance; + let multiSigWrapper: MultiSigWrapper; + let txId: number; + let initialSecondsTimeLocked: number; + let rpc: RPC; + + before(async () => { + rpc = new RPC(); + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + + describe('changeTimeLock', () => { + describe('initially non-time-locked', async () => { + before('deploy a walet', async () => { + multiSig = await deployer.deployAsync(ContractName.MultiSigWalletWithTimeLock, [ + owners, + SIGNATURES_REQUIRED, + 0, + ]); + multiSigWrapper = new MultiSigWrapper(multiSig); + + const secondsTimeLocked = await multiSig.secondsTimeLocked(); + initialSecondsTimeLocked = secondsTimeLocked.toNumber(); + }); + it('should throw when not called by wallet', async () => { + return expect(multiSig.changeTimeLock(SECONDS_TIME_LOCKED, { from: owners[0] })).to.be.rejectedWith( + constants.REVERT, + ); + }); + + it('should throw without enough confirmations', async () => { + const destination = multiSig.address; + const from = owners[0]; + const dataParams = { + name: 'changeTimeLock', + abi: MULTI_SIG_ABI, + args: [SECONDS_TIME_LOCKED], + }; + const txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); + const subRes = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(subRes.logs[0]) as LogWithDecodedArgs< + SubmissionContractEventArgs + >; + + txId = log.args.transactionId.toNumber(); + return expect(multiSig.executeTransaction(txId, { from: owners[0] })).to.be.rejectedWith( + constants.REVERT, + ); + }); + + it('should set confirmation time with enough confirmations', async () => { + const destination = multiSig.address; + const from = owners[0]; + const dataParams = { + name: 'changeTimeLock', + abi: MULTI_SIG_ABI, + args: [SECONDS_TIME_LOCKED], + }; + let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); + const subRes = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(subRes.logs[0]) as LogWithDecodedArgs< + SubmissionContractEventArgs + >; + + txId = log.args.transactionId.toNumber(); + txHash = await multiSig.confirmTransaction(txId, { from: owners[1] }); + const res = await zeroEx.awaitTransactionMinedAsync(txHash); + expect(res.logs).to.have.length(2); + + const blockNum = await web3Wrapper.getBlockNumberAsync(); + const blockInfo = await web3Wrapper.getBlockAsync(blockNum); + const timestamp = new BigNumber(blockInfo.timestamp); + const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes.call(txId)); + + expect(timestamp).to.be.bignumber.equal(confirmationTimeBigNum); + }); + + it('should be executable with enough confirmations and secondsTimeLocked of 0', async () => { + const destination = multiSig.address; + const from = owners[0]; + const dataParams = { + name: 'changeTimeLock', + abi: MULTI_SIG_ABI, + args: [SECONDS_TIME_LOCKED], + }; + let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); + const subRes = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(subRes.logs[0]) as LogWithDecodedArgs< + SubmissionContractEventArgs + >; + + txId = log.args.transactionId.toNumber(); + txHash = await multiSig.confirmTransaction(txId, { from: owners[1] }); + + expect(initialSecondsTimeLocked).to.be.equal(0); + + txHash = await multiSig.executeTransaction(txId, { from: owners[0] }); + const res = await zeroEx.awaitTransactionMinedAsync(txHash); + expect(res.logs).to.have.length(2); + + const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call()); + expect(secondsTimeLocked).to.be.bignumber.equal(SECONDS_TIME_LOCKED); + }); + }); + describe('initially time-locked', async () => { + before('deploy a walet', async () => { + multiSig = await deployer.deployAsync(ContractName.MultiSigWalletWithTimeLock, [ + owners, + SIGNATURES_REQUIRED, + SECONDS_TIME_LOCKED, + ]); + multiSigWrapper = new MultiSigWrapper(multiSig); + + const secondsTimeLocked = await multiSig.secondsTimeLocked(); + initialSecondsTimeLocked = secondsTimeLocked.toNumber(); + const destination = multiSig.address; + const from = owners[0]; + const dataParams = { + name: 'changeTimeLock', + abi: MULTI_SIG_ABI, + args: [newSecondsTimeLocked], + }; + let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); + const subRes = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(subRes.logs[0]) as LogWithDecodedArgs< + SubmissionContractEventArgs + >; + txId = log.args.transactionId.toNumber(); + txHash = await multiSig.confirmTransaction(txId, { + from: owners[1], + }); + const confRes = await zeroEx.awaitTransactionMinedAsync(txHash); + expect(confRes.logs).to.have.length(2); + }); + const newSecondsTimeLocked = 0; + it('should throw if it has enough confirmations but is not past the time lock', async () => { + return expect(multiSig.executeTransaction(txId, { from: owners[0] })).to.be.rejectedWith( + constants.REVERT, + ); + }); + + it('should execute if it has enough confirmations and is past the time lock', async () => { + await rpc.increaseTimeAsync(SECONDS_TIME_LOCKED); + await multiSig.executeTransaction(txId, { from: owners[0] }); + + const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call()); + expect(secondsTimeLocked).to.be.bignumber.equal(newSecondsTimeLocked); + }); + }); + }); +}); diff --git a/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts b/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts new file mode 100644 index 000000000..f6b7c1d53 --- /dev/null +++ b/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts @@ -0,0 +1,181 @@ +import { LogWithDecodedArgs, ZeroEx } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; +import { AbiDecoder } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as chai from 'chai'; +import * as Web3 from 'web3'; + +import { artifacts } from '../util/artifacts'; +import { constants } from '../util/constants'; +import { crypto } from '../util/crypto'; +import { MultiSigWrapper } from '../util/multi_sig_wrapper'; +import { ContractName, SubmissionContractEventArgs, TransactionDataParams } from '../util/types'; + +import { chaiSetup } from './utils/chai_setup'; +import { deployer } from './utils/deployer'; +const PROXY_ABI = artifacts.TokenTransferProxyArtifact.networks[constants.TESTRPC_NETWORK_ID].abi; +const MUTISIG_WALLET_WITH_TIME_LOCK_EXCEPT_REMOVE_AUTHORIZED_ADDRESS_ABI = + artifacts.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact.networks[constants.TESTRPC_NETWORK_ID] + .abi; + +chaiSetup.configure(); +const expect = chai.expect; +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); +const abiDecoder = new AbiDecoder([MUTISIG_WALLET_WITH_TIME_LOCK_EXCEPT_REMOVE_AUTHORIZED_ADDRESS_ABI]); + +describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { + const zeroEx = new ZeroEx(web3.currentProvider, { networkId: constants.TESTRPC_NETWORK_ID }); + let owners: string[]; + const requiredApprovals = 2; + const SECONDS_TIME_LOCKED = 1000000; + + // initialize fake addresses + let authorizedAddress: string; + let unauthorizedAddress: string; + + let tokenTransferProxy: Web3.ContractInstance; + let multiSig: Web3.ContractInstance; + let multiSigWrapper: MultiSigWrapper; + + let validDestination: string; + before(async () => { + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + owners = [accounts[0], accounts[1]]; + [authorizedAddress, unauthorizedAddress] = accounts; + const initialOwner = accounts[0]; + tokenTransferProxy = await deployer.deployAsync(ContractName.TokenTransferProxy); + await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, { + from: initialOwner, + }); + multiSig = await deployer.deployAsync(ContractName.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress, [ + owners, + requiredApprovals, + SECONDS_TIME_LOCKED, + tokenTransferProxy.address, + ]); + await tokenTransferProxy.transferOwnership(multiSig.address, { + from: initialOwner, + }); + multiSigWrapper = new MultiSigWrapper(multiSig); + validDestination = tokenTransferProxy.address; + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + + describe('isFunctionRemoveAuthorizedAddress', () => { + it('should throw if data is not for removeAuthorizedAddress', async () => { + const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]); + return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data)).to.be.rejectedWith(constants.REVERT); + }); + + it('should return true if data is for removeAuthorizedAddress', async () => { + const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]); + const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.call(data); + expect(isFunctionRemoveAuthorizedAddress).to.be.true(); + }); + }); + + describe('executeRemoveAuthorizedAddress', () => { + it('should throw without the required confirmations', async () => { + const dataParams: TransactionDataParams = { + name: 'removeAuthorizedAddress', + abi: PROXY_ABI, + args: [authorizedAddress], + }; + const txHash = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); + const res = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = log.args.transactionId.toString(); + + return expect(multiSig.executeRemoveAuthorizedAddress(txId, { from: owners[1] })).to.be.rejectedWith( + constants.REVERT, + ); + }); + + it('should throw if tx destination is not the tokenTransferProxy', async () => { + const invalidTokenTransferProxy = await deployer.deployAsync(ContractName.TokenTransferProxy); + const invalidDestination = invalidTokenTransferProxy.address; + const dataParams: TransactionDataParams = { + name: 'removeAuthorizedAddress', + abi: PROXY_ABI, + args: [authorizedAddress], + }; + const txHash = await multiSigWrapper.submitTransactionAsync(invalidDestination, owners[0], dataParams); + const res = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = log.args.transactionId.toString(); + await multiSig.confirmTransaction(txId, { from: owners[1] }); + const isConfirmed = await multiSig.isConfirmed.call(txId); + expect(isConfirmed).to.be.true(); + + return expect(multiSig.executeRemoveAuthorizedAddress(txId, { from: owners[1] })).to.be.rejectedWith( + constants.REVERT, + ); + }); + + it('should throw if tx data is not for removeAuthorizedAddress', async () => { + const dataParams: TransactionDataParams = { + name: 'addAuthorizedAddress', + abi: PROXY_ABI, + args: [unauthorizedAddress], + }; + const txHash = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); + const res = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = log.args.transactionId.toString(); + await multiSig.confirmTransaction(txId, { from: owners[1] }); + const isConfirmed = await multiSig.isConfirmed.call(txId); + expect(isConfirmed).to.be.true(); + + return expect(multiSig.executeRemoveAuthorizedAddress(txId, { from: owners[1] })).to.be.rejectedWith( + constants.REVERT, + ); + }); + + it('should execute removeAuthorizedAddress for valid tokenTransferProxy if fully confirmed', async () => { + const dataParams: TransactionDataParams = { + name: 'removeAuthorizedAddress', + abi: PROXY_ABI, + args: [authorizedAddress], + }; + const txHash = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); + const res = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = log.args.transactionId.toString(); + await multiSig.confirmTransaction(txId, { from: owners[1] }); + const isConfirmed = await multiSig.isConfirmed.call(txId); + expect(isConfirmed).to.be.true(); + await multiSig.executeRemoveAuthorizedAddress(txId, { from: owners[1] }); + const isAuthorized = await tokenTransferProxy.authorized.call(authorizedAddress); + expect(isAuthorized).to.be.false(); + }); + + it('should throw if already executed', async () => { + const dataParams: TransactionDataParams = { + name: 'removeAuthorizedAddress', + abi: PROXY_ABI, + args: [authorizedAddress], + }; + const txHash = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); + const res = await zeroEx.awaitTransactionMinedAsync(txHash); + const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = log.args.transactionId.toString(); + await multiSig.confirmTransaction(txId, { from: owners[1] }); + const isConfirmed = await multiSig.isConfirmed(txId); + expect(isConfirmed).to.be.true(); + await multiSig.executeRemoveAuthorizedAddress(txId, { from: owners[1] }); + const tx = await multiSig.transactions(txId); + const isExecuted = tx[3]; + expect(isExecuted).to.be.true(); + return expect(multiSig.executeRemoveAuthorizedAddress(txId, { from: owners[1] })).to.be.rejectedWith( + constants.REVERT, + ); + }); + }); +}); diff --git a/packages/contracts/test/ts/token_registry.ts b/packages/contracts/test/token_registry.ts index d1c551565..2a270dc2f 100644 --- a/packages/contracts/test/ts/token_registry.ts +++ b/packages/contracts/test/token_registry.ts @@ -1,22 +1,42 @@ import { ZeroEx } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; +import * as Web3 from 'web3'; -import { Artifacts } from '../../util/artifacts'; -import { constants } from '../../util/constants'; -import { TokenRegWrapper } from '../../util/token_registry_wrapper'; -import { ContractInstance } from '../../util/types'; +import { constants } from '../util/constants'; +import { TokenRegWrapper } from '../util/token_registry_wrapper'; +import { ContractName } from '../util/types'; import { chaiSetup } from './utils/chai_setup'; +import { deployer } from './utils/deployer'; -const { TokenRegistry } = new Artifacts(artifacts); chaiSetup.configure(); const expect = chai.expect; - -contract('TokenRegistry', (accounts: string[]) => { - const owner = accounts[0]; - const notOwner = accounts[1]; +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); + +describe('TokenRegistry', () => { + let owner: string; + let notOwner: string; + let tokenReg: Web3.ContractInstance; + let tokenRegWrapper: TokenRegWrapper; + before(async () => { + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + owner = accounts[0]; + notOwner = accounts[1]; + tokenReg = await deployer.deployAsync(ContractName.TokenRegistry); + tokenRegWrapper = new TokenRegWrapper(tokenReg); + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); const tokenAddress1 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x1'), 20, false).toString('hex')}`; const tokenAddress2 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x2'), 20, false).toString('hex')}`; @@ -48,14 +68,6 @@ contract('TokenRegistry', (accounts: string[]) => { swarmHash: constants.NULL_BYTES, }; - let tokenReg: ContractInstance; - let tokenRegWrapper: TokenRegWrapper; - - beforeEach(async () => { - tokenReg = await TokenRegistry.new(); - tokenRegWrapper = new TokenRegWrapper(tokenReg); - }); - describe('addToken', () => { it('should throw when not called by owner', async () => { return expect(tokenRegWrapper.addTokenAsync(token1, notOwner)).to.be.rejectedWith(constants.REVERT); @@ -125,10 +137,9 @@ contract('TokenRegistry', (accounts: string[]) => { }); it('should change the token name when called by owner', async () => { - const res = await tokenReg.setTokenName(token1.address, token2.name, { + await tokenReg.setTokenName(token1.address, token2.name, { from: owner, }); - expect(res.logs).to.have.length(1); const [newData, oldData] = await Promise.all([ tokenRegWrapper.getTokenByNameAsync(token2.name), tokenRegWrapper.getTokenByNameAsync(token1.name), @@ -165,8 +176,7 @@ contract('TokenRegistry', (accounts: string[]) => { }); it('should change the token symbol when called by owner', async () => { - const res = await tokenReg.setTokenSymbol(token1.address, token2.symbol, { from: owner }); - expect(res.logs).to.have.length(1); + await tokenReg.setTokenSymbol(token1.address, token2.symbol, { from: owner }); const [newData, oldData] = await Promise.all([ tokenRegWrapper.getTokenBySymbolAsync(token2.symbol), tokenRegWrapper.getTokenBySymbolAsync(token1.symbol), @@ -207,10 +217,9 @@ contract('TokenRegistry', (accounts: string[]) => { it('should remove token metadata when called by owner', async () => { const index = 0; - const res = await tokenReg.removeToken(token1.address, index, { + await tokenReg.removeToken(token1.address, index, { from: owner, }); - expect(res.logs).to.have.length(1); const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address); expect(tokenData).to.be.deep.equal(nullToken); }); diff --git a/packages/contracts/test/ts/token_transfer_proxy/auth.ts b/packages/contracts/test/token_transfer_proxy/auth.ts index 9ae0a8fc3..b2bfc6b65 100644 --- a/packages/contracts/test/ts/token_transfer_proxy/auth.ts +++ b/packages/contracts/test/token_transfer_proxy/auth.ts @@ -1,44 +1,50 @@ +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; +import * as Web3 from 'web3'; -import { constants } from '../../../util/constants'; -import { ContractInstance } from '../../../util/types'; +import { constants } from '../../util/constants'; +import { ContractName } from '../../util/types'; import { chaiSetup } from '../utils/chai_setup'; +import { deployer } from '../utils/deployer'; chaiSetup.configure(); const expect = chai.expect; -const TokenTransferProxy = artifacts.require('./db/TokenTransferProxy.sol'); - -contract('TokenTransferProxy', (accounts: string[]) => { - const owner = accounts[0]; - const notOwner = accounts[1]; - - let tokenTransferProxy: ContractInstance; - let authorized: string; - let notAuthorized = owner; +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); +describe('TokenTransferProxy', () => { + let owner: string; + let notOwner: string; + let address: string; + let tokenTransferProxy: Web3.ContractInstance; before(async () => { - tokenTransferProxy = await TokenTransferProxy.deployed(); + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + owner = address = accounts[0]; + notOwner = accounts[1]; + tokenTransferProxy = await deployer.deployAsync(ContractName.TokenTransferProxy); + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); }); - describe('addAuthorizedAddress', () => { it('should throw if not called by owner', async () => { return expect(tokenTransferProxy.addAuthorizedAddress(notOwner, { from: notOwner })).to.be.rejectedWith( constants.REVERT, ); }); - it('should allow owner to add an authorized address', async () => { - await tokenTransferProxy.addAuthorizedAddress(notAuthorized, { - from: owner, - }); - authorized = notAuthorized; - notAuthorized = null; - const isAuthorized = await tokenTransferProxy.authorized.call(authorized); + await tokenTransferProxy.addAuthorizedAddress(address, { from: owner }); + const isAuthorized = await tokenTransferProxy.authorized(address); expect(isAuthorized).to.be.true(); }); - it('should throw if owner attempts to authorize a duplicate address', async () => { - return expect(tokenTransferProxy.addAuthorizedAddress(authorized, { from: owner })).to.be.rejectedWith( + await tokenTransferProxy.addAuthorizedAddress(address, { from: owner }); + return expect(tokenTransferProxy.addAuthorizedAddress(address, { from: owner })).to.be.rejectedWith( constants.REVERT, ); }); @@ -46,27 +52,26 @@ contract('TokenTransferProxy', (accounts: string[]) => { describe('removeAuthorizedAddress', () => { it('should throw if not called by owner', async () => { + await tokenTransferProxy.addAuthorizedAddress(address, { from: owner }); return expect( - tokenTransferProxy.removeAuthorizedAddress(authorized, { + tokenTransferProxy.removeAuthorizedAddress(address, { from: notOwner, }), ).to.be.rejectedWith(constants.REVERT); }); it('should allow owner to remove an authorized address', async () => { - await tokenTransferProxy.removeAuthorizedAddress(authorized, { + await tokenTransferProxy.addAuthorizedAddress(address, { from: owner }); + await tokenTransferProxy.removeAuthorizedAddress(address, { from: owner, }); - notAuthorized = authorized; - authorized = null; - - const isAuthorized = await tokenTransferProxy.authorized.call(notAuthorized); + const isAuthorized = await tokenTransferProxy.authorized(address); expect(isAuthorized).to.be.false(); }); it('should throw if owner attempts to remove an address that is not authorized', async () => { return expect( - tokenTransferProxy.removeAuthorizedAddress(notAuthorized, { + tokenTransferProxy.removeAuthorizedAddress(address, { from: owner, }), ).to.be.rejectedWith(constants.REVERT); @@ -76,24 +81,19 @@ contract('TokenTransferProxy', (accounts: string[]) => { describe('getAuthorizedAddresses', () => { it('should return all authorized addresses', async () => { const initial = await tokenTransferProxy.getAuthorizedAddresses(); - expect(initial).to.have.length(1); - await tokenTransferProxy.addAuthorizedAddress(notAuthorized, { + expect(initial).to.have.length(0); + await tokenTransferProxy.addAuthorizedAddress(address, { from: owner, }); - - authorized = notAuthorized; - notAuthorized = null; const afterAdd = await tokenTransferProxy.getAuthorizedAddresses(); - expect(afterAdd).to.have.length(2); - expect(afterAdd).to.include(authorized); + expect(afterAdd).to.have.length(1); + expect(afterAdd).to.include(address); - await tokenTransferProxy.removeAuthorizedAddress(authorized, { + await tokenTransferProxy.removeAuthorizedAddress(address, { from: owner, }); - notAuthorized = authorized; - authorized = null; const afterRemove = await tokenTransferProxy.getAuthorizedAddresses(); - expect(afterRemove).to.have.length(1); + expect(afterRemove).to.have.length(0); }); }); }); diff --git a/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts b/packages/contracts/test/token_transfer_proxy/transfer_from.ts index e1aff6dae..bd7adcfae 100644 --- a/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts +++ b/packages/contracts/test/token_transfer_proxy/transfer_from.ts @@ -1,47 +1,55 @@ +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; +import * as Web3 from 'web3'; -import { Artifacts } from '../../../util/artifacts'; -import { Balances } from '../../../util/balances'; -import { constants } from '../../../util/constants'; -import { ContractInstance } from '../../../util/types'; +import { Balances } from '../../util/balances'; +import { constants } from '../../util/constants'; +import { ContractName } from '../../util/types'; import { chaiSetup } from '../utils/chai_setup'; +import { deployer } from '../utils/deployer'; chaiSetup.configure(); const expect = chai.expect; -const { TokenTransferProxy, DummyToken, TokenRegistry } = new Artifacts(artifacts); +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); -contract('TokenTransferProxy', (accounts: string[]) => { +describe('TokenTransferProxy', () => { + let accounts: string[]; + let owner: string; + let notAuthorized: string; const INIT_BAL = 100000000; const INIT_ALLOW = 100000000; - const owner = accounts[0]; - const notAuthorized = owner; - - let tokenTransferProxy: ContractInstance; - let tokenRegistry: ContractInstance; - let rep: ContractInstance; + let tokenTransferProxy: Web3.ContractInstance; + let rep: Web3.ContractInstance; let dmyBalances: Balances; before(async () => { - [tokenTransferProxy, tokenRegistry] = await Promise.all([ - TokenTransferProxy.deployed(), - TokenRegistry.deployed(), - ]); - const repAddress = await tokenRegistry.getTokenAddressBySymbol('REP'); - rep = DummyToken.at(repAddress); + accounts = await web3Wrapper.getAvailableAddressesAsync(); + owner = notAuthorized = accounts[0]; + tokenTransferProxy = await deployer.deployAsync(ContractName.TokenTransferProxy); + rep = await deployer.deployAsync(ContractName.DummyToken); dmyBalances = new Balances([rep], [accounts[0], accounts[1]]); await Promise.all([ - rep.approve(TokenTransferProxy.address, INIT_ALLOW, { + rep.approve(tokenTransferProxy.address, INIT_ALLOW, { from: accounts[0], }), rep.setBalance(accounts[0], INIT_BAL, { from: owner }), - rep.approve(TokenTransferProxy.address, INIT_ALLOW, { + rep.approve(tokenTransferProxy.address, INIT_ALLOW, { from: accounts[1], }), rep.setBalance(accounts[1], INIT_BAL, { from: owner }), ]); }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); describe('transferFrom', () => { it('should throw when called by an unauthorized address', async () => { diff --git a/packages/contracts/test/ts/multi_sig_with_time_lock.ts b/packages/contracts/test/ts/multi_sig_with_time_lock.ts deleted file mode 100644 index ea939a758..000000000 --- a/packages/contracts/test/ts/multi_sig_with_time_lock.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { RPC } from '@0xproject/dev-utils'; -import { BigNumber, promisify } from '@0xproject/utils'; -import * as chai from 'chai'; -import Web3 = require('web3'); - -import * as multiSigWalletJSON from '../../build/contracts/MultiSigWalletWithTimeLock.json'; -import * as truffleConf from '../../truffle.js'; -import { Artifacts } from '../../util/artifacts'; -import { constants } from '../../util/constants'; -import { MultiSigWrapper } from '../../util/multi_sig_wrapper'; -import { ContractInstance } from '../../util/types'; - -import { chaiSetup } from './utils/chai_setup'; - -const { MultiSigWalletWithTimeLock } = new Artifacts(artifacts); - -const MULTI_SIG_ABI = (multiSigWalletJSON as any).abi; -chaiSetup.configure(); -const expect = chai.expect; - -// In order to benefit from type-safety, we re-assign the global web3 instance injected by Truffle -// with type `any` to a variable of type `Web3`. -const web3: Web3 = (global as any).web3; - -contract('MultiSigWalletWithTimeLock', (accounts: string[]) => { - const owners = [accounts[0], accounts[1]]; - const SECONDS_TIME_LOCKED = 10000; - - let multiSig: ContractInstance; - let multiSigWrapper: MultiSigWrapper; - let txId: number; - let initialSecondsTimeLocked: number; - let rpc: RPC; - - before(async () => { - multiSig = await MultiSigWalletWithTimeLock.deployed(); - multiSigWrapper = new MultiSigWrapper(multiSig); - - const secondsTimeLocked = await multiSig.secondsTimeLocked.call(); - initialSecondsTimeLocked = secondsTimeLocked.toNumber(); - const rpcUrl = `http://${truffleConf.networks.development.host}:${truffleConf.networks.development.port}`; - rpc = new RPC(rpcUrl); - }); - - describe('changeTimeLock', () => { - it('should throw when not called by wallet', async () => { - return expect(multiSig.changeTimeLock(SECONDS_TIME_LOCKED, { from: owners[0] })).to.be.rejectedWith( - constants.REVERT, - ); - }); - - it('should throw without enough confirmations', async () => { - const destination = multiSig.address; - const from = owners[0]; - const dataParams = { - name: 'changeTimeLock', - abi: MULTI_SIG_ABI, - args: [SECONDS_TIME_LOCKED], - }; - const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - - txId = subRes.logs[0].args.transactionId.toNumber(); - return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT); - }); - - it('should set confirmation time with enough confirmations', async () => { - const res = await multiSig.confirmTransaction(txId, { from: owners[1] }); - expect(res.logs).to.have.length(2); - const blockNum = await promisify<number>(web3.eth.getBlockNumber)(); - const blockInfo = await promisify<Web3.BlockWithoutTransactionData>(web3.eth.getBlock)(blockNum); - const timestamp = new BigNumber(blockInfo.timestamp); - const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes.call(txId)); - - expect(timestamp).to.be.bignumber.equal(confirmationTimeBigNum); - }); - - it('should be executable with enough confirmations and secondsTimeLocked of 0', async () => { - expect(initialSecondsTimeLocked).to.be.equal(0); - - const res = await multiSig.executeTransaction(txId); - expect(res.logs).to.have.length(2); - - const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call()); - expect(secondsTimeLocked).to.be.bignumber.equal(SECONDS_TIME_LOCKED); - }); - - const newSecondsTimeLocked = 0; - it('should throw if it has enough confirmations but is not past the time lock', async () => { - const destination = multiSig.address; - const from = owners[0]; - const dataParams = { - name: 'changeTimeLock', - abi: MULTI_SIG_ABI, - args: [newSecondsTimeLocked], - }; - const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - - txId = subRes.logs[0].args.transactionId.toNumber(); - const confRes = await multiSig.confirmTransaction(txId, { - from: owners[1], - }); - expect(confRes.logs).to.have.length(2); - - return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT); - }); - - it('should execute if it has enough confirmations and is past the time lock', async () => { - await rpc.increaseTimeAsync(SECONDS_TIME_LOCKED); - await multiSig.executeTransaction(txId); - - const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call()); - expect(secondsTimeLocked).to.be.bignumber.equal(newSecondsTimeLocked); - }); - }); -}); diff --git a/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts b/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts deleted file mode 100644 index 62aa625fe..000000000 --- a/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts +++ /dev/null @@ -1,150 +0,0 @@ -import * as chai from 'chai'; - -import * as tokenTransferProxyJSON from '../../build/contracts/TokenTransferProxy.json'; -import { Artifacts } from '../../util/artifacts'; -import { constants } from '../../util/constants'; -import { crypto } from '../../util/crypto'; -import { MultiSigWrapper } from '../../util/multi_sig_wrapper'; -import { ContractInstance, TransactionDataParams } from '../../util/types'; - -import { chaiSetup } from './utils/chai_setup'; -const { TokenTransferProxy, MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress } = new Artifacts(artifacts); -const PROXY_ABI = (tokenTransferProxyJSON as any).abi; - -chaiSetup.configure(); -const expect = chai.expect; - -contract('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', (accounts: string[]) => { - const owners = [accounts[0], accounts[1]]; - const requiredApprovals = 2; - const SECONDS_TIME_LOCKED = 1000000; - - // initialize fake addresses - const authorizedAddress = `0x${crypto - .solSHA3([accounts[0]]) - .slice(0, 20) - .toString('hex')}`; - const unauthorizedAddress = `0x${crypto - .solSHA3([accounts[1]]) - .slice(0, 20) - .toString('hex')}`; - - let tokenTransferProxy: ContractInstance; - let multiSig: ContractInstance; - let multiSigWrapper: MultiSigWrapper; - - let validDestination: string; - - beforeEach(async () => { - const initialOwner = accounts[0]; - tokenTransferProxy = await TokenTransferProxy.new({ from: initialOwner }); - await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, { - from: initialOwner, - }); - multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.new( - owners, - requiredApprovals, - SECONDS_TIME_LOCKED, - tokenTransferProxy.address, - ); - await tokenTransferProxy.transferOwnership(multiSig.address, { - from: initialOwner, - }); - multiSigWrapper = new MultiSigWrapper(multiSig); - validDestination = tokenTransferProxy.address; - }); - - describe('isFunctionRemoveAuthorizedAddress', () => { - it('should throw if data is not for removeAuthorizedAddress', async () => { - const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]); - return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data)).to.be.rejectedWith(constants.REVERT); - }); - - it('should return true if data is for removeAuthorizedAddress', async () => { - const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]); - const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.call(data); - expect(isFunctionRemoveAuthorizedAddress).to.be.true(); - }); - }); - - describe('executeRemoveAuthorizedAddress', () => { - it('should throw without the required confirmations', async () => { - const dataParams: TransactionDataParams = { - name: 'removeAuthorizedAddress', - abi: PROXY_ABI, - args: [authorizedAddress], - }; - const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); - const txId = res.logs[0].args.transactionId.toString(); - - return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT); - }); - - it('should throw if tx destination is not the tokenTransferProxy', async () => { - const invalidTokenTransferProxy = await TokenTransferProxy.new(); - const invalidDestination = invalidTokenTransferProxy.address; - const dataParams: TransactionDataParams = { - name: 'removeAuthorizedAddress', - abi: PROXY_ABI, - args: [authorizedAddress], - }; - const res = await multiSigWrapper.submitTransactionAsync(invalidDestination, owners[0], dataParams); - const txId = res.logs[0].args.transactionId.toString(); - await multiSig.confirmTransaction(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed.call(txId); - expect(isConfirmed).to.be.true(); - - return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT); - }); - - it('should throw if tx data is not for removeAuthorizedAddress', async () => { - const dataParams: TransactionDataParams = { - name: 'addAuthorizedAddress', - abi: PROXY_ABI, - args: [unauthorizedAddress], - }; - const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); - const txId = res.logs[0].args.transactionId.toString(); - await multiSig.confirmTransaction(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed.call(txId); - expect(isConfirmed).to.be.true(); - - return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT); - }); - - it('should execute removeAuthorizedAddress for valid tokenTransferProxy if fully confirmed', async () => { - const dataParams: TransactionDataParams = { - name: 'removeAuthorizedAddress', - abi: PROXY_ABI, - args: [authorizedAddress], - }; - const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); - const txId = res.logs[0].args.transactionId.toString(); - await multiSig.confirmTransaction(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed.call(txId); - expect(isConfirmed).to.be.true(); - await multiSig.executeRemoveAuthorizedAddress(txId); - - const isAuthorized = await tokenTransferProxy.authorized.call(authorizedAddress); - expect(isAuthorized).to.be.false(); - }); - - it('should throw if already executed', async () => { - const dataParams: TransactionDataParams = { - name: 'removeAuthorizedAddress', - abi: PROXY_ABI, - args: [authorizedAddress], - }; - const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); - const txId = res.logs[0].args.transactionId.toString(); - await multiSig.confirmTransaction(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed.call(txId); - expect(isConfirmed).to.be.true(); - await multiSig.executeRemoveAuthorizedAddress(txId); - const tx = await multiSig.transactions.call(txId); - const isExecuted = tx[3]; - expect(isExecuted).to.be.true(); - return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT); - }); - }); -}); diff --git a/packages/contracts/test/ts/unlimited_allowance_token.ts b/packages/contracts/test/unlimited_allowance_token.ts index c90a52095..7f4fef987 100644 --- a/packages/contracts/test/ts/unlimited_allowance_token.ts +++ b/packages/contracts/test/unlimited_allowance_token.ts @@ -1,37 +1,48 @@ import { ZeroEx } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import * as Web3 from 'web3'; -import { Artifacts } from '../../util/artifacts'; -import { constants } from '../../util/constants'; -import { ContractInstance } from '../../util/types'; +import { constants } from '../util/constants'; +import { ContractName } from '../util/types'; import { chaiSetup } from './utils/chai_setup'; +import { deployer } from './utils/deployer'; -const { DummyToken } = new Artifacts(artifacts); -const web3: Web3 = (global as any).web3; +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); chaiSetup.configure(); const expect = chai.expect; +const blockchainLifecycle = new BlockchainLifecycle(); -contract('UnlimitedAllowanceToken', (accounts: string[]) => { +describe('UnlimitedAllowanceToken', () => { + let owner: string; + let spender: string; const config = { networkId: constants.TESTRPC_NETWORK_ID, }; const zeroEx = new ZeroEx(web3.currentProvider, config); - const owner = accounts[0]; - const spender = accounts[1]; const MAX_MINT_VALUE = new BigNumber(100000000000000000000); let tokenAddress: string; - let token: ContractInstance; + let token: Web3.ContractInstance; - beforeEach(async () => { - token = await DummyToken.new({ from: owner }); + before(async () => { + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + owner = accounts[0]; + spender = accounts[1]; + token = await deployer.deployAsync(ContractName.DummyToken); await token.mint(MAX_MINT_VALUE, { from: owner }); tokenAddress = token.address; }); - + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); describe('transfer', () => { it('should transfer balance from sender to receiver', async () => { const receiver = spender; diff --git a/packages/contracts/test/ts/unlimited_allowance_token_v2.ts b/packages/contracts/test/unlimited_allowance_token_v2.ts index 1b29a02ba..440cc11ac 100644 --- a/packages/contracts/test/ts/unlimited_allowance_token_v2.ts +++ b/packages/contracts/test/unlimited_allowance_token_v2.ts @@ -1,37 +1,48 @@ import { ZeroEx } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import * as Web3 from 'web3'; -import { Artifacts } from '../../util/artifacts'; -import { constants } from '../../util/constants'; -import { ContractInstance } from '../../util/types'; +import { constants } from '../util/constants'; +import { ContractName } from '../util/types'; import { chaiSetup } from './utils/chai_setup'; +import { deployer } from './utils/deployer'; -const { DummyTokenV2 } = new Artifacts(artifacts); -const web3: Web3 = (global as any).web3; chaiSetup.configure(); const expect = chai.expect; +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); -contract('UnlimitedAllowanceTokenV2', (accounts: string[]) => { +describe('UnlimitedAllowanceTokenV2', () => { const config = { networkId: constants.TESTRPC_NETWORK_ID, }; const zeroEx = new ZeroEx(web3.currentProvider, config); - const owner = accounts[0]; - const spender = accounts[1]; + let owner: string; + let spender: string; const MAX_MINT_VALUE = new BigNumber(100000000000000000000); let tokenAddress: string; - let token: ContractInstance; + let token: Web3.ContractInstance; - beforeEach(async () => { - token = await DummyTokenV2.new({ from: owner }); + before(async () => { + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + owner = accounts[0]; + spender = accounts[1]; + token = await deployer.deployAsync(ContractName.DummyToken_v2); await token.mint(MAX_MINT_VALUE, { from: owner }); tokenAddress = token.address; }); - + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); describe('transfer', () => { it('should throw if owner has insufficient balance', async () => { const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner); diff --git a/packages/contracts/test/ts/utils/chai_setup.ts b/packages/contracts/test/utils/chai_setup.ts index 078edd309..078edd309 100644 --- a/packages/contracts/test/ts/utils/chai_setup.ts +++ b/packages/contracts/test/utils/chai_setup.ts diff --git a/packages/contracts/test/utils/deployer.ts b/packages/contracts/test/utils/deployer.ts new file mode 100644 index 000000000..4c6eeff2b --- /dev/null +++ b/packages/contracts/test/utils/deployer.ts @@ -0,0 +1,16 @@ +import { Deployer } from '@0xproject/deployer'; +import { devConstants } from '@0xproject/dev-utils'; +import * as path from 'path'; + +import { constants } from '../../util/constants'; + +const deployerOpts = { + artifactsDir: `${path.resolve('build')}/artifacts`, + jsonrpcPort: devConstants.RPC_PORT, + networkId: constants.TESTRPC_NETWORK_ID, + defaults: { + gas: devConstants.GAS_ESTIMATE, + }, +}; + +export const deployer = new Deployer(deployerOpts); diff --git a/packages/contracts/test/ts/zrx_token.ts b/packages/contracts/test/zrx_token.ts index 766c94c2a..1844a67af 100644 --- a/packages/contracts/test/ts/zrx_token.ts +++ b/packages/contracts/test/zrx_token.ts @@ -1,60 +1,70 @@ import { ZeroEx } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; -import Web3 = require('web3'); +import * as Web3 from 'web3'; -import { Artifacts } from '../../util/artifacts'; -import { constants } from '../../util/constants'; -import { ContractInstance } from '../../util/types'; +import { constants } from '../util/constants'; +import { ContractName } from '../util/types'; import { chaiSetup } from './utils/chai_setup'; +import { deployer } from './utils/deployer'; chaiSetup.configure(); const expect = chai.expect; -const { Exchange, ZRXToken } = new Artifacts(artifacts); -const web3: Web3 = (global as any).web3; +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); -contract('ZRXToken', (accounts: string[]) => { - const owner = accounts[0]; - const spender = accounts[1]; +describe('ZRXToken', () => { + let owner: string; + let spender: string; let zeroEx: ZeroEx; let MAX_UINT: BigNumber; - let zrx: ContractInstance; + let zrx: Web3.ContractInstance; let zrxAddress: string; - beforeEach(async () => { + before(async () => { + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + owner = accounts[0]; + spender = accounts[1]; zeroEx = new ZeroEx(web3.currentProvider, { - exchangeContractAddress: Exchange.address, networkId: constants.TESTRPC_NETWORK_ID, }); - zrx = await ZRXToken.new(); + zrx = await deployer.deployAsync(ContractName.ZRXToken); zrxAddress = zrx.address; MAX_UINT = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; }); - + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); describe('constants', () => { it('should have 18 decimals', async () => { - const decimals = new BigNumber(await zrx.decimals.call()); + const decimals = new BigNumber(await zrx.decimals()); const expectedDecimals = 18; expect(decimals).to.be.bignumber.equal(expectedDecimals); }); it('should have a total supply of 1 billion tokens', async () => { - const totalSupply = new BigNumber(await zrx.totalSupply.call()); + const totalSupply = new BigNumber(await zrx.totalSupply()); const expectedTotalSupply = 1000000000; expect(ZeroEx.toUnitAmount(totalSupply, 18)).to.be.bignumber.equal(expectedTotalSupply); }); it('should be named 0x Protocol Token', async () => { - const name = await zrx.name.call(); + const name = await zrx.name(); const expectedName = '0x Protocol Token'; expect(name).to.be.equal(expectedName); }); it('should have the symbol ZRX', async () => { - const symbol = await zrx.symbol.call(); + const symbol = await zrx.symbol(); const expectedSymbol = 'ZRX'; expect(symbol).to.be.equal(expectedSymbol); }); @@ -63,7 +73,7 @@ contract('ZRXToken', (accounts: string[]) => { describe('constructor', () => { it('should initialize owner balance to totalSupply', async () => { const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner); - const totalSupply = new BigNumber(await zrx.totalSupply.call()); + const totalSupply = new BigNumber(await zrx.totalSupply()); expect(totalSupply).to.be.bignumber.equal(ownerBalance); }); }); @@ -73,8 +83,7 @@ contract('ZRXToken', (accounts: string[]) => { const receiver = spender; const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner); const amountToTransfer = new BigNumber(1); - const txHash = await zeroEx.token.transferAsync(zrxAddress, owner, receiver, amountToTransfer); - await zeroEx.awaitTransactionMinedAsync(txHash); + await zeroEx.token.transferAsync(zrxAddress, owner, receiver, amountToTransfer); const finalOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner); const finalReceiverBalance = await zeroEx.token.getBalanceAsync(zrxAddress, receiver); @@ -96,10 +105,9 @@ contract('ZRXToken', (accounts: string[]) => { it('should return false if owner has insufficient balance', async () => { const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner); const amountToTransfer = ownerBalance.plus(1); - const txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer, { + await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer, { gasLimit: constants.MAX_TOKEN_APPROVE_GAS, }); - await zeroEx.awaitTransactionMinedAsync(txHash); const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender }); expect(didReturnTrue).to.be.false(); }); @@ -126,14 +134,12 @@ contract('ZRXToken', (accounts: string[]) => { const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner); const amountToTransfer = initOwnerBalance; const initSpenderAllowance = MAX_UINT; - let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance, { + await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance, { gasLimit: constants.MAX_TOKEN_APPROVE_GAS, }); - await zeroEx.awaitTransactionMinedAsync(txHash); - txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, { + await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, { gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS, }); - await zeroEx.awaitTransactionMinedAsync(txHash); const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender); expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance); @@ -144,12 +150,10 @@ contract('ZRXToken', (accounts: string[]) => { const initSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender); const amountToTransfer = initOwnerBalance; const initSpenderAllowance = initOwnerBalance; - let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance); - await zeroEx.awaitTransactionMinedAsync(txHash); - txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, { + await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance); + await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, { gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS, }); - await zeroEx.awaitTransactionMinedAsync(txHash); const newOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner); const newSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender); @@ -161,12 +165,10 @@ contract('ZRXToken', (accounts: string[]) => { it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => { const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner); const amountToTransfer = initOwnerBalance; - let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer); - await zeroEx.awaitTransactionMinedAsync(txHash); - txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, { + await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer); + await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, { gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS, }); - await zeroEx.awaitTransactionMinedAsync(txHash); const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender); expect(newSpenderAllowance).to.be.bignumber.equal(0); diff --git a/packages/contracts/truffle.js b/packages/contracts/truffle.js deleted file mode 100644 index 630f4cf8b..000000000 --- a/packages/contracts/truffle.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - networks: { - development: { - host: "localhost", - port: 8545, - network_id: "*", // Match any network id - }, - kovan: { - host: "localhost", - port: 8546, - network_id: "42", - gas: 4612388, - }, - }, - test_directory: "lib/test", - migrations_directory: "lib/migrations", -}; diff --git a/packages/contracts/tsconfig.json b/packages/contracts/tsconfig.json index 38008a542..0c1b3bc16 100644 --- a/packages/contracts/tsconfig.json +++ b/packages/contracts/tsconfig.json @@ -4,8 +4,6 @@ "outDir": "lib", "baseUrl": ".", "declaration": false, - "strictNullChecks": false, - "strictFunctionTypes": false, "allowJs": true }, "include": [ diff --git a/packages/contracts/util/artifacts.ts b/packages/contracts/util/artifacts.ts index ecb18cbce..145b1db3b 100644 --- a/packages/contracts/util/artifacts.ts +++ b/packages/contracts/util/artifacts.ts @@ -1,28 +1,27 @@ -export class Artifacts { - public Migrations: any; - public TokenTransferProxy: any; - public TokenRegistry: any; - public MultiSigWalletWithTimeLock: any; - public Exchange: any; - public ZRXToken: any; - public DummyToken: any; - public DummyTokenV2: any; - public EtherToken: any; - public MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress: any; - public MaliciousToken: any; - constructor(artifacts: any) { - this.Migrations = artifacts.require('Migrations'); - this.TokenTransferProxy = artifacts.require('TokenTransferProxy'); - this.TokenRegistry = artifacts.require('TokenRegistry'); - this.MultiSigWalletWithTimeLock = artifacts.require('MultiSigWalletWithTimeLock'); - this.Exchange = artifacts.require('Exchange'); - this.ZRXToken = artifacts.require('ZRXToken'); - this.DummyToken = artifacts.require('DummyToken'); - this.DummyTokenV2 = artifacts.require('DummyToken_v2'); - this.EtherToken = artifacts.require('WETH9'); - this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require( - 'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', - ); - this.MaliciousToken = artifacts.require('MaliciousToken'); - } -} +import * as DummyTokenArtifact from '../build/artifacts/DummyToken.json'; +import * as DummyTokenV2Artifact from '../build/artifacts/DummyToken_v2.json'; +import * as ExchangeArtifact from '../build/artifacts/Exchange.json'; +import * as MaliciousTokenArtifact from '../build/artifacts/MaliciousToken.json'; +import * as MultiSigWalletWithTimeLockArtifact from '../build/artifacts/MultiSigWalletWithTimeLock.json'; +import * as MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact from '../build/artifacts/MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.json'; +import * as TokenArtifact from '../build/artifacts/Token.json'; +import * as TokenRegistryArtifact from '../build/artifacts/TokenRegistry.json'; +import * as TokenTransferProxyArtifact from '../build/artifacts/TokenTransferProxy.json'; +import * as EtherTokenArtifact from '../build/artifacts/WETH9.json'; +import * as ZRXArtifact from '../build/artifacts/ZRXToken.json'; + +import { Artifact } from './types'; + +export const artifacts = { + ZRXArtifact: (ZRXArtifact as any) as Artifact, + DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact, + DummyTokenV2Artifact: (DummyTokenV2Artifact as any) as Artifact, + TokenArtifact: (TokenArtifact as any) as Artifact, + ExchangeArtifact: (ExchangeArtifact as any) as Artifact, + EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact, + TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact, + MaliciousTokenArtifact: (MaliciousTokenArtifact as any) as Artifact, + TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact, + MultiSigWalletWithTimeLockArtifact: (MultiSigWalletWithTimeLockArtifact as any) as Artifact, + MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact: (MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact as any) as Artifact, +}; diff --git a/packages/contracts/util/balances.ts b/packages/contracts/util/balances.ts index 6a1659ab1..5bcb5145f 100644 --- a/packages/contracts/util/balances.ts +++ b/packages/contracts/util/balances.ts @@ -1,12 +1,13 @@ import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; +import * as Web3 from 'web3'; -import { BalancesByOwner, ContractInstance } from './types'; +import { BalancesByOwner } from './types'; export class Balances { - private _tokenContractInstances: ContractInstance[]; + private _tokenContractInstances: Web3.ContractInstance[]; private _ownerAddresses: string[]; - constructor(tokenContractInstances: ContractInstance[], ownerAddresses: string[]) { + constructor(tokenContractInstances: Web3.ContractInstance[], ownerAddresses: string[]) { this._tokenContractInstances = tokenContractInstances; this._ownerAddresses = ownerAddresses; } diff --git a/packages/contracts/util/exchange_wrapper.ts b/packages/contracts/util/exchange_wrapper.ts index ca79f92c4..7a07239f5 100644 --- a/packages/contracts/util/exchange_wrapper.ts +++ b/packages/contracts/util/exchange_wrapper.ts @@ -1,14 +1,17 @@ +import { TransactionReceiptWithDecodedLogs, ZeroEx } from '0x.js'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; +import * as Web3 from 'web3'; import { formatters } from './formatters'; import { Order } from './order'; -import { ContractInstance } from './types'; export class ExchangeWrapper { - private _exchange: ContractInstance; - constructor(exchangeContractInstance: ContractInstance) { + private _exchange: Web3.ContractInstance; + private _zeroEx: ZeroEx; + constructor(exchangeContractInstance: Web3.ContractInstance, zeroEx: ZeroEx) { this._exchange = exchangeContractInstance; + this._zeroEx = zeroEx; } public async fillOrderAsync( order: Order, @@ -17,10 +20,10 @@ export class ExchangeWrapper { fillTakerTokenAmount?: BigNumber; shouldThrowOnInsufficientBalanceOrAllowance?: boolean; } = {}, - ) { + ): Promise<TransactionReceiptWithDecodedLogs> { const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); - const tx = await this._exchange.fillOrder( + const txHash = await this._exchange.fillOrder( params.orderAddresses, params.orderValues, params.fillTakerTokenAmount, @@ -30,24 +33,36 @@ export class ExchangeWrapper { params.s, { from }, ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); _.each(tx.logs, log => wrapLogBigNumbers(log)); return tx; } - public async cancelOrderAsync(order: Order, from: string, opts: { cancelTakerTokenAmount?: BigNumber } = {}) { + public async cancelOrderAsync( + order: Order, + from: string, + opts: { cancelTakerTokenAmount?: BigNumber } = {}, + ): Promise<TransactionReceiptWithDecodedLogs> { const params = order.createCancel(opts.cancelTakerTokenAmount); - const tx = await this._exchange.cancelOrder( + const txHash = await this._exchange.cancelOrder( params.orderAddresses, params.orderValues, params.cancelTakerTokenAmount, { from }, ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); _.each(tx.logs, log => wrapLogBigNumbers(log)); return tx; } - public async fillOrKillOrderAsync(order: Order, from: string, opts: { fillTakerTokenAmount?: BigNumber } = {}) { + public async fillOrKillOrderAsync( + order: Order, + from: string, + opts: { fillTakerTokenAmount?: BigNumber } = {}, + ): Promise<TransactionReceiptWithDecodedLogs> { const shouldThrowOnInsufficientBalanceOrAllowance = true; const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); - const tx = await this._exchange.fillOrKillOrder( + const txHash = await this._exchange.fillOrKillOrder( params.orderAddresses, params.orderValues, params.fillTakerTokenAmount, @@ -56,6 +71,8 @@ export class ExchangeWrapper { params.s, { from }, ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); _.each(tx.logs, log => wrapLogBigNumbers(log)); return tx; } @@ -66,14 +83,14 @@ export class ExchangeWrapper { fillTakerTokenAmounts?: BigNumber[]; shouldThrowOnInsufficientBalanceOrAllowance?: boolean; } = {}, - ) { + ): Promise<TransactionReceiptWithDecodedLogs> { const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; const params = formatters.createBatchFill( orders, shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmounts, ); - const tx = await this._exchange.batchFillOrders( + const txHash = await this._exchange.batchFillOrders( params.orderAddresses, params.orderValues, params.fillTakerTokenAmounts, @@ -83,16 +100,23 @@ export class ExchangeWrapper { params.s, { from }, ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); _.each(tx.logs, log => wrapLogBigNumbers(log)); return tx; } public async batchFillOrKillOrdersAsync( orders: Order[], from: string, - opts: { fillTakerTokenAmounts?: BigNumber[] } = {}, - ) { - const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts); - const tx = await this._exchange.batchFillOrKillOrders( + opts: { fillTakerTokenAmounts?: BigNumber[]; shouldThrowOnInsufficientBalanceOrAllowance?: boolean } = {}, + ): Promise<TransactionReceiptWithDecodedLogs> { + const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; + const params = formatters.createBatchFill( + orders, + shouldThrowOnInsufficientBalanceOrAllowance, + opts.fillTakerTokenAmounts, + ); + const txHash = await this._exchange.batchFillOrKillOrders( params.orderAddresses, params.orderValues, params.fillTakerTokenAmounts, @@ -101,24 +125,23 @@ export class ExchangeWrapper { params.s, { from }, ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); _.each(tx.logs, log => wrapLogBigNumbers(log)); return tx; } public async fillOrdersUpToAsync( orders: Order[], from: string, - opts: { - fillTakerTokenAmount?: BigNumber; - shouldThrowOnInsufficientBalanceOrAllowance?: boolean; - } = {}, - ) { + opts: { fillTakerTokenAmount: BigNumber; shouldThrowOnInsufficientBalanceOrAllowance?: boolean }, + ): Promise<TransactionReceiptWithDecodedLogs> { const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; const params = formatters.createFillUpTo( orders, shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount, ); - const tx = await this._exchange.fillOrdersUpTo( + const txHash = await this._exchange.fillOrdersUpTo( params.orderAddresses, params.orderValues, params.fillTakerTokenAmount, @@ -128,6 +151,8 @@ export class ExchangeWrapper { params.s, { from }, ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); _.each(tx.logs, log => wrapLogBigNumbers(log)); return tx; } @@ -135,14 +160,16 @@ export class ExchangeWrapper { orders: Order[], from: string, opts: { cancelTakerTokenAmounts?: BigNumber[] } = {}, - ) { + ): Promise<TransactionReceiptWithDecodedLogs> { const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts); - const tx = await this._exchange.batchCancelOrders( + const txHash = await this._exchange.batchCancelOrders( params.orderAddresses, params.orderValues, params.cancelTakerTokenAmounts, { from }, ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); _.each(tx.logs, log => wrapLogBigNumbers(log)); return tx; } diff --git a/packages/contracts/util/formatters.ts b/packages/contracts/util/formatters.ts index 0d0ef6df4..e16fe8d45 100644 --- a/packages/contracts/util/formatters.ts +++ b/packages/contracts/util/formatters.ts @@ -35,9 +35,9 @@ export const formatters = { order.params.expirationTimestampInSec, order.params.salt, ]); - batchFill.v.push(order.params.v); - batchFill.r.push(order.params.r); - batchFill.s.push(order.params.s); + batchFill.v.push(order.params.v as number); + batchFill.r.push(order.params.r as string); + batchFill.s.push(order.params.s as string); if (fillTakerTokenAmounts.length < orders.length) { batchFill.fillTakerTokenAmounts.push(order.params.takerTokenAmount); } @@ -74,9 +74,9 @@ export const formatters = { order.params.expirationTimestampInSec, order.params.salt, ]); - fillUpTo.v.push(order.params.v); - fillUpTo.r.push(order.params.r); - fillUpTo.s.push(order.params.s); + fillUpTo.v.push(order.params.v as number); + fillUpTo.r.push(order.params.r as string); + fillUpTo.s.push(order.params.s as string); }); return fillUpTo; }, diff --git a/packages/contracts/util/multi_sig_wrapper.ts b/packages/contracts/util/multi_sig_wrapper.ts index 0e2e671ec..0a066df53 100644 --- a/packages/contracts/util/multi_sig_wrapper.ts +++ b/packages/contracts/util/multi_sig_wrapper.ts @@ -3,10 +3,10 @@ import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; import * as Web3 from 'web3'; -import { ContractInstance, TransactionDataParams } from './types'; +import { TransactionDataParams } from './types'; export class MultiSigWrapper { - private _multiSig: ContractInstance; + private _multiSig: Web3.ContractInstance; public static encodeFnArgs(name: string, abi: Web3.AbiDefinition[], args: any[]) { const abiEntity = _.find(abi, { name }) as Web3.MethodAbi; if (_.isUndefined(abiEntity)) { @@ -21,7 +21,7 @@ export class MultiSigWrapper { }); return funcSig + argsData.join(''); } - constructor(multiSigContractInstance: ContractInstance) { + constructor(multiSigContractInstance: Web3.ContractInstance) { this._multiSig = multiSigContractInstance; } public async submitTransactionAsync( diff --git a/packages/contracts/util/order.ts b/packages/contracts/util/order.ts index e202d485b..57bb2bcbf 100644 --- a/packages/contracts/util/order.ts +++ b/packages/contracts/util/order.ts @@ -1,19 +1,17 @@ -import { BigNumber, promisify } from '@0xproject/utils'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; -import Web3 = require('web3'); import { crypto } from './crypto'; import { OrderParams } from './types'; -// In order to benefit from type-safety, we re-assign the global web3 instance injected by Truffle -// with type `any` to a variable of type `Web3`. -const web3: Web3 = (global as any).web3; - export class Order { public params: OrderParams; - constructor(params: OrderParams) { + private _web3Wrapper: Web3Wrapper; + constructor(web3Wrapper: Web3Wrapper, params: OrderParams) { this.params = params; + this._web3Wrapper = web3Wrapper; } public isValidSignature() { const { v, r, s } = this.params; @@ -32,7 +30,7 @@ export class Order { } public async signAsync() { const orderHash = this._getOrderHash(); - const signature = await promisify<string>(web3.eth.sign)(this.params.maker, orderHash); + const signature = await this._web3Wrapper.signTransactionAsync(this.params.maker, orderHash); const { v, r, s } = ethUtil.fromRpcSig(signature); this.params = _.assign(this.params, { orderHashHex: orderHash, diff --git a/packages/contracts/util/order_factory.ts b/packages/contracts/util/order_factory.ts index a45877de0..2b50f13e8 100644 --- a/packages/contracts/util/order_factory.ts +++ b/packages/contracts/util/order_factory.ts @@ -1,5 +1,6 @@ import { ZeroEx } from '0x.js'; import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import { Order } from './order'; @@ -7,10 +8,12 @@ import { DefaultOrderParams, OptionalOrderParams, OrderParams } from './types'; export class OrderFactory { private _defaultOrderParams: DefaultOrderParams; - constructor(defaultOrderParams: DefaultOrderParams) { + private _web3Wrapper: Web3Wrapper; + constructor(web3Wrapper: Web3Wrapper, defaultOrderParams: DefaultOrderParams) { this._defaultOrderParams = defaultOrderParams; + this._web3Wrapper = web3Wrapper; } - public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) { + public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}): Promise<Order> { const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000)); const orderParams: OrderParams = _.assign( {}, @@ -22,7 +25,7 @@ export class OrderFactory { this._defaultOrderParams, customOrderParams, ); - const order = new Order(orderParams); + const order = new Order(this._web3Wrapper, orderParams); await order.signAsync(); return order; } diff --git a/packages/contracts/util/token_registry_wrapper.ts b/packages/contracts/util/token_registry_wrapper.ts index 07a577dea..033b72d10 100644 --- a/packages/contracts/util/token_registry_wrapper.ts +++ b/packages/contracts/util/token_registry_wrapper.ts @@ -1,8 +1,10 @@ -import { ContractInstance, Token } from './types'; +import * as Web3 from 'web3'; + +import { Token } from './types'; export class TokenRegWrapper { - private _tokenReg: ContractInstance; - constructor(tokenRegContractInstance: ContractInstance) { + private _tokenReg: Web3.ContractInstance; + constructor(tokenRegContractInstance: Web3.ContractInstance) { this._tokenReg = tokenRegContractInstance; } public addTokenAsync(token: Token, from: string) { diff --git a/packages/contracts/util/types.ts b/packages/contracts/util/types.ts index e511ca9f4..0db04cd76 100644 --- a/packages/contracts/util/types.ts +++ b/packages/contracts/util/types.ts @@ -7,6 +7,10 @@ export interface BalancesByOwner { }; } +export interface SubmissionContractEventArgs { + transactionId: BigNumber; +} + export interface BatchFillOrders { orderAddresses: string[][]; orderValues: BigNumber[][]; @@ -108,12 +112,38 @@ export interface TokenInfoByNetwork { live: Token[]; } -// Named type aliases to improve readability -export type ContractInstance = any; - export enum ExchangeContractErrs { ERROR_ORDER_EXPIRED, ERROR_ORDER_FULLY_FILLED_OR_CANCELLED, ERROR_ROUNDING_ERROR_TOO_LARGE, ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE, } + +export enum ContractName { + TokenTransferProxy = 'TokenTransferProxy', + TokenRegistry = 'TokenRegistry', + MultiSigWalletWithTimeLock = 'MultiSigWalletWithTimeLock', + Exchange = 'Exchange', + ZRXToken = 'ZRXToken', + DummyToken = 'DummyToken', + DummyToken_v2 = 'DummyToken_v2', + EtherToken = 'WETH9', + MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = 'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', + MaliciousToken = 'MaliciousToken', +} + +export interface Artifact { + contract_name: ContractName; + networks: { + [networkId: number]: { + abi: Web3.ContractAbi; + solc_version: string; + keccak256: string; + optimizer_enabled: number; + unlinked_binary: string; + updated_at: number; + address: string; + constructor_args: string; + }; + }; +} diff --git a/packages/deployer/package.json b/packages/deployer/package.json index 723c4a465..8bff8445c 100644 --- a/packages/deployer/package.json +++ b/packages/deployer/package.json @@ -2,7 +2,8 @@ "name": "@0xproject/deployer", "version": "0.0.4", "description": "Smart contract deployer of 0x protocol", - "main": "lib/src/cli.js", + "main": "lib/src/index.js", + "types": "lib/src/index.d.ts", "scripts": { "build": "yarn clean && copyfiles 'test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc", "test": "npm run build; mocha lib/test/*_test.js", @@ -27,12 +28,13 @@ "homepage": "https://github.com/0xProject/0x.js/packages/deployer/README.md", "devDependencies": { "copyfiles": "^1.2.0", + "web3-typescript-typings": "^0.9.4", "types-bn": "^0.0.1", "typescript": "~2.6.1", "web3-typescript-typings": "^0.9.7" }, "dependencies": { - "@0xproject/utils": "^0.1.3", + "@0xproject/utils": "^0.2.1", "@0xproject/web3-wrapper": "^0.1.8", "lodash": "^4.17.4", "solc": "^0.4.18", diff --git a/packages/deployer/src/index.ts b/packages/deployer/src/index.ts new file mode 100644 index 000000000..06dc9e596 --- /dev/null +++ b/packages/deployer/src/index.ts @@ -0,0 +1 @@ +export { Deployer } from './deployer'; diff --git a/packages/deployer/src/utils/contract.ts b/packages/deployer/src/utils/contract.ts index 546e82dfb..9c57751ff 100644 --- a/packages/deployer/src/utils/contract.ts +++ b/packages/deployer/src/utils/contract.ts @@ -28,16 +28,16 @@ export class Contract implements Web3.ContractInstance { _.forEach(functionsAbi, (functionAbi: Web3.MethodAbi) => { if (functionAbi.constant) { const cbStyleCallFunction = this._contract[functionAbi.name].call; - this[functionAbi.name] = { - callAsync: promisify(cbStyleCallFunction, this._contract), - }; + this[functionAbi.name] = promisify(cbStyleCallFunction, this._contract); + this[functionAbi.name].call = promisify(cbStyleCallFunction, this._contract); } else { const cbStyleFunction = this._contract[functionAbi.name]; + const cbStyleCallFunction = this._contract[functionAbi.name].call; const cbStyleEstimateGasFunction = this._contract[functionAbi.name].estimateGas; - this[functionAbi.name] = { - estimateGasAsync: promisify(cbStyleEstimateGasFunction, this._contract), - sendTransactionAsync: this._promisifyWithDefaultParams(cbStyleFunction), - }; + this[functionAbi.name] = this._promisifyWithDefaultParams(cbStyleFunction); + this[functionAbi.name].estimateGasAsync = promisify(cbStyleEstimateGasFunction); + this[functionAbi.name].sendTransactionAsync = this._promisifyWithDefaultParams(cbStyleFunction); + this[functionAbi.name].call = promisify(cbStyleCallFunction, this._contract); } }); } diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index bd77b7c20..ec0872a46 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -21,17 +21,20 @@ "devDependencies": { "@0xproject/tslint-config": "^0.4.5", "@types/lodash": "^4.14.86", + "@0xproject/types": "^0.1.5", "npm-run-all": "^4.1.2", "shx": "^0.2.2", "tslint": "5.8.0", "types-bn": "^0.0.1", - "types-ethereumjs-util": "0xProject/types-ethereumjs-util", + "types-ethereumjs-util": "0xproject/types-ethereumjs-util", "typescript": "~2.6.1" }, "dependencies": { "@0xproject/utils": "^0.2.3", "ethereumjs-util": "^5.1.2", "lodash": "^4.17.4", - "request-promise-native": "^1.0.5" + "request-promise-native": "^1.0.5", + "web3": "^0.20.0", + "web3-provider-engine": "^13.0.1" } } diff --git a/packages/dev-utils/src/blockchain_lifecycle.ts b/packages/dev-utils/src/blockchain_lifecycle.ts index 18f5d5c61..c46902f76 100644 --- a/packages/dev-utils/src/blockchain_lifecycle.ts +++ b/packages/dev-utils/src/blockchain_lifecycle.ts @@ -3,8 +3,8 @@ import { RPC } from './rpc'; export class BlockchainLifecycle { private _rpc: RPC; private _snapshotIdsStack: number[]; - constructor(url: string) { - this._rpc = new RPC(url); + constructor() { + this._rpc = new RPC(); this._snapshotIdsStack = []; } // TODO: In order to run these tests on an actual node, we should check if we are running against diff --git a/packages/dev-utils/src/constants.ts b/packages/dev-utils/src/constants.ts new file mode 100644 index 000000000..4f7b4202a --- /dev/null +++ b/packages/dev-utils/src/constants.ts @@ -0,0 +1,5 @@ +export const constants = { + RPC_URL: 'http://localhost:8545', + RPC_PORT: 8545, + GAS_ESTIMATE: 1000000, +}; diff --git a/packages/dev-utils/src/globals.d.ts b/packages/dev-utils/src/globals.d.ts new file mode 100644 index 000000000..7b132ee28 --- /dev/null +++ b/packages/dev-utils/src/globals.d.ts @@ -0,0 +1,2 @@ +declare module 'web3-provider-engine'; +declare module 'web3-provider-engine/subproviders/rpc'; diff --git a/packages/dev-utils/src/index.ts b/packages/dev-utils/src/index.ts index 9ba0cb5cf..e899ac206 100644 --- a/packages/dev-utils/src/index.ts +++ b/packages/dev-utils/src/index.ts @@ -1,2 +1,4 @@ export { RPC } from './rpc'; export { BlockchainLifecycle } from './blockchain_lifecycle'; +export { web3Factory } from './web3_factory'; +export { constants as devConstants } from './constants'; diff --git a/packages/dev-utils/src/rpc.ts b/packages/dev-utils/src/rpc.ts index 36f8b1ef9..47a359263 100644 --- a/packages/dev-utils/src/rpc.ts +++ b/packages/dev-utils/src/rpc.ts @@ -1,11 +1,13 @@ import * as ethUtil from 'ethereumjs-util'; import * as request from 'request-promise-native'; +import { constants } from './constants'; + export class RPC { private _url: string; private _id: number; - constructor(url: string) { - this._url = url; + constructor() { + this._url = constants.RPC_URL; this._id = 0; } public async takeSnapshotAsync(): Promise<number> { diff --git a/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts b/packages/dev-utils/src/subproviders/empty_wallet_subprovider.ts index 53f2be83d..8c1fdfdb2 100644 --- a/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts +++ b/packages/dev-utils/src/subproviders/empty_wallet_subprovider.ts @@ -1,4 +1,4 @@ -import { JSONRPCPayload } from '../../../src/types'; +import { JSONRPCPayload } from '@0xproject/types'; /* * This class implements the web3-provider-engine subprovider interface and returns diff --git a/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts b/packages/dev-utils/src/subproviders/fake_gas_estimate_subprovider.ts index e1113a851..b455a0ed7 100644 --- a/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts +++ b/packages/dev-utils/src/subproviders/fake_gas_estimate_subprovider.ts @@ -1,4 +1,4 @@ -import { JSONRPCPayload } from '../../../src/types'; +import { JSONRPCPayload } from '@0xproject/types'; /* * This class implements the web3-provider-engine subprovider interface and returns diff --git a/packages/0x.js/test/utils/web3_factory.ts b/packages/dev-utils/src/web3_factory.ts index 26c26e03d..26c26e03d 100644 --- a/packages/0x.js/test/utils/web3_factory.ts +++ b/packages/dev-utils/src/web3_factory.ts diff --git a/packages/dev-utils/tsconfig.json b/packages/dev-utils/tsconfig.json index b28e45170..bdf315d59 100644 --- a/packages/dev-utils/tsconfig.json +++ b/packages/dev-utils/tsconfig.json @@ -6,6 +6,7 @@ "include": [ "./src/**/*", "../../node_modules/types-bn/index.d.ts", + "../../node_modules/web3-typescript-typings/index.d.ts", "../../node_modules/types-ethereumjs-util/index.d.ts" ] } diff --git a/packages/json-schemas/tsconfig.json b/packages/json-schemas/tsconfig.json index 88a467ccb..10354fa33 100644 --- a/packages/json-schemas/tsconfig.json +++ b/packages/json-schemas/tsconfig.json @@ -3,5 +3,10 @@ "compilerOptions": { "outDir": "lib" }, - "include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"] + "include": [ + "./src/**/*", + "./test/**/*", + "../../node_modules/web3-typescript-typings/index.d.ts", + "../../node_modules/chai-typescript-typings/index.d.ts" + ] } diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 251b63e19..9381689b1 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -49,7 +49,7 @@ "types-bn": "^0.0.1", "types-ethereumjs-util": "0xproject/types-ethereumjs-util", "typescript": "~2.6.1", - "web3-typescript-typings": "^0.7.2", + "web3-typescript-typings": "^0.9.5", "webpack": "^3.1.0" } } diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json index 3b616ba3a..f4497ff5d 100644 --- a/packages/tslint-config/package.json +++ b/packages/tslint-config/package.json @@ -8,22 +8,12 @@ "clean": "shx rm -rf lib", "lint": "tslint --project . 'rules/**/*.ts'" }, - "files": [ - "tslint.js", - "README.md", - "LICENSE" - ], + "files": ["tslint.js", "README.md", "LICENSE"], "repository": { "type": "git", "url": "git://github.com/0xProject/0x.js.git" }, - "keywords": [ - "tslint", - "config", - "0xProject", - "typescript", - "ts" - ], + "keywords": ["tslint", "config", "0xProject", "typescript", "ts"], "author": { "name": "Fabio Berger", "email": "fabio@0xproject.com" diff --git a/packages/tslint-config/tslint.json b/packages/tslint-config/tslint.json index 971588b08..44a8517dc 100644 --- a/packages/tslint-config/tslint.json +++ b/packages/tslint-config/tslint.json @@ -44,7 +44,6 @@ "no-string-throw": true, "no-submodule-imports": false, "no-unnecessary-type-assertion": true, - "no-unused-variable": [true, { "ignore-pattern": "^_\\d*" }], "no-implicit-dependencies": [true, "dev"], "number-literal-format": true, "object-literal-sort-keys": false, diff --git a/packages/types/package.json b/packages/types/package.json index 0c17e52ea..1abcf79ad 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -22,10 +22,11 @@ "@0xproject/tslint-config": "^0.4.5", "shx": "^0.2.2", "tslint": "5.8.0", + "web3-typescript-typings": "^0.9.5", "typescript": "~2.6.1" }, "dependencies": { - "@0xproject/utils": "^0.2.3", + "bignumber.js": "~4.1.0", "web3": "^0.20.0" } } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 9cf9bc7af..7b53b52c4 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,4 +1,4 @@ -import { BigNumber } from '@0xproject/utils'; +import { BigNumber } from 'bignumber.js'; import * as Web3 from 'web3'; export interface TxData { @@ -25,3 +25,34 @@ export interface TransactionReceipt { contractAddress: string | null; logs: Web3.LogEntry[]; } + +export interface JSONRPCPayload { + params: any[]; + method: string; +} + +export enum AbiType { + Function = 'function', + Constructor = 'constructor', + Event = 'event', + Fallback = 'fallback', +} + +export type ContractEventArg = string | BigNumber; + +export interface DecodedLogArgs { + [argName: string]: ContractEventArg; +} + +export interface LogWithDecodedArgs<ArgsType> extends Web3.DecodedLogEntry<ArgsType> {} +export type RawLog = Web3.LogEntry; +export enum SolidityTypes { + Address = 'address', + Uint256 = 'uint256', + Uint8 = 'uint8', + Uint = 'uint', +} + +export interface TransactionReceiptWithDecodedLogs extends TransactionReceipt { + logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>; +} diff --git a/packages/utils/package.json b/packages/utils/package.json index a1cf4c24a..db82f8040 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -20,15 +20,18 @@ "homepage": "https://github.com/0xProject/0x.js/packages/utils/README.md", "devDependencies": { "@0xproject/tslint-config": "^0.4.5", + "@0xproject/types": "^0.1.5", "@types/lodash": "^4.14.86", "npm-run-all": "^4.1.2", "shx": "^0.2.2", "tslint": "5.8.0", + "web3-typescript-typings": "^0.9.5", "typescript": "~2.6.1" }, "dependencies": { "bignumber.js": "~4.1.0", "js-sha3": "^0.7.0", - "lodash": "^4.17.4" + "lodash": "^4.17.4", + "web3": "^0.20.0" } } diff --git a/packages/0x.js/src/utils/abi_decoder.ts b/packages/utils/src/abi_decoder.ts index bbd2a0b1d..f96ee2edb 100644 --- a/packages/0x.js/src/utils/abi_decoder.ts +++ b/packages/utils/src/abi_decoder.ts @@ -1,9 +1,9 @@ -import { BigNumber } from '@0xproject/utils'; +import { AbiType, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes } from '@0xproject/types'; import * as _ from 'lodash'; import * as Web3 from 'web3'; import * as SolidityCoder from 'web3/lib/solidity/coder'; -import { AbiType, ContractEventArgs, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes } from '../types'; +import { BigNumber } from './configured_bignumber'; export class AbiDecoder { private _savedABIs: Web3.AbiDefinition[] = []; @@ -21,9 +21,7 @@ export class AbiDecoder { _.map(abiArrays, this._addABI.bind(this)); } // This method can only decode logs from the 0x & ERC20 smart contracts - public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>( - log: Web3.LogEntry, - ): LogWithDecodedArgs<ArgsType> | RawLog { + public tryToDecodeLogOrNoop<ArgsType>(log: Web3.LogEntry): LogWithDecodedArgs<ArgsType> | RawLog { const methodId = log.topics[0]; const event = this._methodIds[methodId]; if (_.isUndefined(event)) { @@ -40,7 +38,7 @@ export class AbiDecoder { _.map(event.inputs, (param: Web3.EventParameter) => { // Indexed parameters are stored in topics. Non-indexed ones in decodedData - let value = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++]; + let value: BigNumber | string = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++]; if (param.type === SolidityTypes.Address) { value = AbiDecoder._padZeros(new BigNumber(value).toString(16)); } else if ( diff --git a/packages/utils/src/globals.d.ts b/packages/utils/src/globals.d.ts new file mode 100644 index 000000000..ade9e59db --- /dev/null +++ b/packages/utils/src/globals.d.ts @@ -0,0 +1,3 @@ +declare module 'web3/lib/solidity/coder' { + const decodeParams: (types: string[], data: string) => any[]; +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 2768e49ab..39dede41f 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -3,3 +3,4 @@ export { addressUtils } from './address_utils'; export { classUtils } from './class_utils'; export { intervalUtils } from './interval_utils'; export { BigNumber } from './configured_bignumber'; +export { AbiDecoder } from './abi_decoder'; diff --git a/packages/web3-typescript-typings/package.json b/packages/web3-typescript-typings/package.json index 03d8e333e..4737088b0 100644 --- a/packages/web3-typescript-typings/package.json +++ b/packages/web3-typescript-typings/package.json @@ -12,9 +12,7 @@ "url": "git+https://github.com/0xProject/0x.js.git" }, "author": "Fabio Berger", - "contributors": [ - "Leonid Logvinov <logvinov.leon@gmail.com>" - ], + "contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"], "license": "Apache-2.0", "bugs": { "url": "https://github.com/0xProject/0x.js/issues" @@ -22,7 +20,7 @@ "homepage": "https://github.com/0xProject/0x.js/packages/web3-typescript-typings#readme", "devDependencies": { "@types/bignumber.js": "^4.0.2", - "tslint": "^5.5.0", + "tslint": "5.8.0", "tslint-config-0xproject": "^0.0.2", "typescript": "~2.6.1" }, diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts index c4826f2be..a2878fc2a 100644 --- a/packages/web3-wrapper/src/index.ts +++ b/packages/web3-wrapper/src/index.ts @@ -134,6 +134,10 @@ export class Web3Wrapper { const gas = await promisify<number>(this._web3.eth.estimateGas)({ data }); return gas; } + public async sendTransactionAsync(txData: Web3.TxData): Promise<string> { + const txHash = await promisify<string>(this._web3.eth.sendTransaction)(txData); + return txHash; + } private async _sendRawPayloadAsync<A>(payload: Web3.JSONRPCRequestPayload): Promise<A> { const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider); const response = await promisify<Web3.JSONRPCResponsePayload>(sendAsync)(payload); diff --git a/packages/website/package.json b/packages/website/package.json index 0acc6429a..a5a9eb00a 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -8,9 +8,12 @@ "clean": "shx rm -f public/bundle*", "lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'", "dev": "webpack-dev-server --content-base public --https", - "update_contracts": "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../website/contracts; done;", - "deploy_staging": "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers", - "deploy_live": "npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers" + "update_contracts": + "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../website/contracts; done;", + "deploy_staging": + "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers", + "deploy_live": + "npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers" }, "config": { "artifacts": "Mintable" @@ -2,14 +2,6 @@ # yarn lockfile v1 -"@0xproject/utils@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@0xproject/utils/-/utils-0.1.3.tgz#58a9c7e19ab7710e0af17a0c2f1c7fc1b3140e85" - dependencies: - bignumber.js "~4.1.0" - js-sha3 "^0.7.0" - lodash "^4.17.4" - "@types/accounting@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/accounting/-/accounting-0.4.1.tgz#865d9f5694fd7c438fba34eb4bc82eec6f34cdd5" @@ -1291,10 +1283,6 @@ big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" -bignumber.js@^4.0.2, bignumber.js@~4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" - "bignumber.js@git+https://github.com/debris/bignumber.js#master": version "2.0.7" resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9" @@ -1307,6 +1295,10 @@ bignumber.js@^4.0.2, bignumber.js@~4.1.0: version "2.0.7" resolved "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" +bignumber.js@~4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" + binary-extensions@^1.0.0: version "1.11.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" @@ -1698,10 +1690,6 @@ chai-bignumber@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/chai-bignumber/-/chai-bignumber-2.0.2.tgz#de6c219c690b2d66b646ad6930096f9ba2199643" -chai-typescript-typings@^0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/chai-typescript-typings/-/chai-typescript-typings-0.0.0.tgz#52e076d72cf29129c94ab1dba6e33ce3828a0724" - chai@^4.0.1: version "4.1.2" resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" @@ -1973,13 +1961,7 @@ commander@2.11.0: version "2.11.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" -commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" - -commander@^2.12.1, commander@^2.9.0: +commander@^2.9.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" @@ -2599,12 +2581,6 @@ debug@2.2.0, debug@~2.2.0: dependencies: ms "0.7.1" -debug@2.6.8: - version "2.6.8" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" - dependencies: - ms "2.0.0" - debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6.8: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2766,10 +2742,6 @@ dharma-loan-frame@^0.0.12: react-svg-loader "^1.1.1" urlencode "^1.1.0" -diff@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" - diff@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" @@ -3972,17 +3944,6 @@ glob2base@^0.0.12: dependencies: find-index "^0.1.1" -glob@7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@~7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" @@ -4118,18 +4079,10 @@ graceful-fs@~1.2.0: version "1.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - growl@1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" -growl@1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" - gulp-util@^3.0.0: version "3.0.8" resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" @@ -5021,10 +4974,6 @@ js-sha3@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.3.1.tgz#86122802142f0828502a0d1dee1d95e253bb0243" -js-sha3@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.6.1.tgz#5b89f77a7477679877f58c4a075240934b1f95c0" - js-sha3@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.7.0.tgz#0a5c57b36f79882573b2d84051f8bb85dd1bd63a" @@ -5033,7 +4982,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.6.1, js-yaml@^3.7.0: +js-yaml@^3.6.1: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: @@ -5102,7 +5051,7 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.0, json-stringify-safe@~5.0 version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" -json3@3.3.2, json3@^3.3.2: +json3@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" @@ -5424,21 +5373,10 @@ lodash-es@^4.2.0, lodash-es@^4.2.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - lodash._basecopy@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" -lodash._basecreate@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" - lodash._basetostring@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" @@ -5488,14 +5426,6 @@ lodash.camelcase@^3.0.1: dependencies: lodash._createcompounder "^3.0.0" -lodash.create@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" - dependencies: - lodash._baseassign "^3.0.0" - lodash._basecreate "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash.deburr@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash.deburr/-/lodash.deburr-3.2.0.tgz#6da8f54334a366a7cf4c4c76ef8d80aa1b365ed5" @@ -5979,23 +5909,6 @@ mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdi dependencies: minimist "0.0.8" -mocha@^3.4.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" - dependencies: - browser-stdout "1.3.0" - commander "2.9.0" - debug "2.6.8" - diff "3.2.0" - escape-string-regexp "1.0.5" - glob "7.1.1" - growl "1.9.2" - he "1.1.1" - json3 "3.3.2" - lodash.create "3.1.1" - mkdirp "0.5.1" - supports-color "3.1.2" - mocha@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" @@ -6476,10 +6389,6 @@ ordered-read-streams@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" -original-require@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/original-require/-/original-require-1.0.1.tgz#0f130471584cd33511c5ec38c8d59213f9ac5e20" - original@>=0.0.5: version "1.0.0" resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b" @@ -7765,7 +7674,7 @@ request-promise-core@1.1.1: dependencies: lodash "^4.13.1" -request-promise-native@^1.0.4, request-promise-native@^1.0.5: +request-promise-native@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" dependencies: @@ -8331,16 +8240,6 @@ sockjs@0.3.19: faye-websocket "^0.10.0" uuid "^3.0.1" -solc@0.4.18: - version "0.4.18" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.18.tgz#83ac6d871dd16a9710e67dbb76dad7f614100702" - dependencies: - fs-extra "^0.30.0" - memorystream "^0.3.1" - require-from-string "^1.1.0" - semver "^5.3.0" - yargs "^4.7.1" - solc@^0.4.18, solc@^0.4.2: version "0.4.19" resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.19.tgz#1af1c4c292a0365a6977d4cbe3fbee7139b4b561" @@ -8722,12 +8621,6 @@ style-loader@0.13.x: dependencies: loader-utils "^1.0.2" -supports-color@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" - dependencies: - has-flag "^1.0.0" - supports-color@4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" @@ -9087,15 +8980,7 @@ truffle-hdwallet-provider@^0.0.3: web3 "^0.18.2" web3-provider-engine "^8.4.0" -truffle@^4.0.1: - version "4.0.4" - resolved "https://registry.yarnpkg.com/truffle/-/truffle-4.0.4.tgz#b447cb3b0469054413b5ff421f6e8baeefddb2be" - dependencies: - mocha "^3.4.2" - original-require "^1.0.1" - solc "0.4.18" - -tslib@^1.0.0, tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1: +tslib@^1.0.0, tslib@^1.7.1, tslib@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac" @@ -9135,23 +9020,6 @@ tslint@5.8.0: tslib "^1.7.1" tsutils "^2.12.1" -tslint@^5.5.0: - version "5.9.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae" - dependencies: - babel-code-frame "^6.22.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^3.2.0" - glob "^7.1.1" - js-yaml "^3.7.0" - minimatch "^3.0.4" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.8.0" - tsutils "^2.12.1" - tsutils@^1.4.0: version "1.9.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-1.9.1.tgz#b9f9ab44e55af9681831d5f28d0aeeaf5c750cb0" @@ -9229,14 +9097,6 @@ types-bn@^0.0.1: dependencies: bn.js "4.11.7" -types-ethereumjs-util@0xProject/types-ethereumjs-util: - version "0.0.6" - resolved "https://codeload.github.com/0xProject/types-ethereumjs-util/tar.gz/0c5058e4f9d6585f7c7c1f88939546acb14323b8" - dependencies: - bn.js "^4.11.7" - buffer "^5.0.6" - rlp "^2.0.0" - types-ethereumjs-util@0xproject/types-ethereumjs-util: version "0.0.6" resolved "https://codeload.github.com/0xproject/types-ethereumjs-util/tar.gz/0c5058e4f9d6585f7c7c1f88939546acb14323b8" @@ -9643,12 +9503,6 @@ web3-provider-engine@^8.4.0: xhr "^2.2.0" xtend "^4.0.1" -web3-typescript-typings@^0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/web3-typescript-typings/-/web3-typescript-typings-0.7.2.tgz#5312bb786936a9c91381eee7af3d02ac21cf13b3" - dependencies: - bignumber.js "^4.0.2" - web3-utils@1.0.0-beta.27: version "1.0.0-beta.27" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.27.tgz#d097d5c336a16b9f6ca9b60af68dd15c0643214b" |