Compare commits
	
		
			126 Commits
		
	
	
		
			@0xproject
			...
			@0xproject
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8df2cc103e | ||
|  | 8e0e9c7d3a | ||
|  | 913930b561 | ||
|  | 994c8db1f3 | ||
|  | 6811bdec40 | ||
|  | 6682abf89d | ||
|  | 78fbf0f7ba | ||
|  | 89547332ee | ||
|  | 75539bf675 | ||
|  | eaeb715e56 | ||
|  | ca55cc99ed | ||
|  | 7cc4a8f5ce | ||
|  | fa35768fc9 | ||
|  | 4d0ff0dce4 | ||
|  | 8aac6e46d4 | ||
|  | 1feac1a308 | ||
|  | d3e42e4b3e | ||
|  | ecf86d1d13 | ||
|  | adc6170f02 | ||
|  | 02600f40d2 | ||
|  | 16ea0348a9 | ||
|  | 57acb8db5c | ||
|  | 2bcb7d5639 | ||
|  | a99e54330a | ||
|  | e219772b2a | ||
|  | 144a507a2e | ||
|  | 5019c51940 | ||
|  | da1071526f | ||
|  | 7ad314472d | ||
|  | 4f6168a982 | ||
|  | 218a872968 | ||
|  | 0043c5e1ac | ||
|  | d0e7046a89 | ||
|  | 52ad16b920 | ||
|  | 5a4c0bff6a | ||
|  | 6205209fbb | ||
|  | 6ebf8a57d1 | ||
|  | c02dfc4fb1 | ||
|  | 9d62e5fb6f | ||
|  | 6f13d107c4 | ||
|  | e56b2ceebb | ||
|  | 7de244ed62 | ||
|  | 1e9147b8bb | ||
|  | 2f65fadeaa | ||
|  | a17091b394 | ||
|  | ed77c6cb54 | ||
|  | bc37cc8a91 | ||
|  | 387363283c | ||
|  | 709026bf1a | ||
|  | f2b2b86786 | ||
|  | d0fbea76d8 | ||
|  | 8269610a5c | ||
|  | 20c88a46d9 | ||
|  | 661029f7cc | ||
|  | 850d32d60c | ||
|  | eb881b9729 | ||
|  | 091ba473ff | ||
|  | fca051c565 | ||
|  | 6463cda204 | ||
|  | d004df56e3 | ||
|  | 359dd482c4 | ||
|  | 89e98240b4 | ||
|  | 8d30058a6d | ||
|  | 69151c06e4 | ||
|  | 2e3c02887e | ||
|  | 7603cef308 | ||
|  | be370c4e19 | ||
|  | c6dece6bd1 | ||
|  | 93a5b3f457 | ||
|  | 4242176d29 | ||
|  | 1cadbeed88 | ||
|  | 86cc011212 | ||
|  | c0facfc28f | ||
|  | ad52a82190 | ||
|  | 60b6ed514f | ||
|  | ef32822b31 | ||
|  | bb0cedd2de | ||
|  | 8175c7c085 | ||
|  | 5c2d725721 | ||
|  | 72571628da | ||
|  | fa6130c907 | ||
|  | 8ccdd54974 | ||
|  | 6c1409b00d | ||
|  | 542a1a11b9 | ||
|  | 63ffa80c5c | ||
|  | 609342be7a | ||
|  | 52394884da | ||
|  | af08177f79 | ||
|  | 45fdfc2d3d | ||
|  | d18554e0e8 | ||
|  | 3c3f9ca85b | ||
|  | 005a02efeb | ||
|  | 6206ebc994 | ||
|  | dd9f5adc2e | ||
|  | 748d805a32 | ||
|  | 4b59bf01b3 | ||
|  | b4faa4851a | ||
|  | f37fcc147c | ||
|  | dc5694e544 | ||
|  | e588f6f8c3 | ||
|  | d227f2ad7c | ||
|  | 97c228031a | ||
|  | ad85011d62 | ||
|  | a70379625d | ||
|  | 7350333129 | ||
|  | 216420fdc5 | ||
|  | c559fbbe8c | ||
|  | 71d68f975c | ||
|  | 390534497e | ||
|  | 3f0ec89f11 | ||
|  | d3aa4f2bc7 | ||
|  | f58f0ddb67 | ||
|  | b08bd0f9ab | ||
|  | 3998b47d84 | ||
|  | d965fdb11d | ||
|  | ddb64b3ec1 | ||
|  | 5055ec8617 | ||
|  | ec3d8a034f | ||
|  | c452294bcc | ||
|  | d5757499bc | ||
|  | 139c8c2e78 | ||
|  | 215e33fa6c | ||
|  | 3d12b84f1d | ||
|  | d8adc88c52 | ||
|  | 5119e49e47 | ||
|  | cfb9f87418 | 
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| *.sol linguist-language=Solidity | ||||
| @@ -2,3 +2,4 @@ lib | ||||
| generated | ||||
| .nyc_output | ||||
| /packages/contracts/build/contracts | ||||
| package.json | ||||
|   | ||||
							
								
								
									
										62
									
								
								ISSUE_TEMPLATE.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								ISSUE_TEMPLATE.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| <!--- Thank you for taking the time to file an Issue --> | ||||
|  | ||||
| <!--- Before submitting please check to see if this issue was already reported --> | ||||
|  | ||||
| <!--- Provide a general summary of the issue in the Title above --> | ||||
|  | ||||
| ## Expected Behavior | ||||
|  | ||||
| <!--- If you're describing a bug, tell us what should happen --> | ||||
|  | ||||
| <!--- If you're suggesting a package change/improvement, tell us how it should work --> | ||||
|  | ||||
| <!--- If you're suggesting a contract or protocol change/improvement, visit our ZEIPs repo --> | ||||
|  | ||||
| ## Current Behavior | ||||
|  | ||||
| <!--- If describing a bug, tell us what happens instead of the expected behavior --> | ||||
|  | ||||
| <!--- If suggesting a change/improvement, explain the difference from current behavior --> | ||||
|  | ||||
| ## Possible Solution | ||||
|  | ||||
| <!--- Not obligatory, but suggest a fix/reason for the bug, --> | ||||
|  | ||||
| <!--- or ideas how to implement the addition or change --> | ||||
|  | ||||
| ## Steps to Reproduce (for bugs) | ||||
|  | ||||
| <!--- Provide a link to a live example, or an unambiguous set of steps to --> | ||||
|  | ||||
| <!--- reproduce this bug. Include code to reproduce, if relevant --> | ||||
|  | ||||
| ``` | ||||
| 1. | ||||
| 2. | ||||
| 3. | ||||
| ``` | ||||
|  | ||||
| ## Context | ||||
|  | ||||
| <!--- How has this issue affected you? What are you trying to accomplish? --> | ||||
|  | ||||
| <!--- Providing context helps us come up with a solution that is most useful in the real world --> | ||||
|  | ||||
| ## Your Environment | ||||
|  | ||||
| <!--- Include as many relevant details about the environment you experienced the bug in --> | ||||
|  | ||||
| |             Package | Version | | ||||
| | ------------------: | :------ | | ||||
| |             `0x.js` | 0.25.0  | | ||||
| | `Exchange Contract` | v1      | | ||||
|  | ||||
| | Network | | ||||
| | ------- | | ||||
| | NAME    | | ||||
|  | ||||
| <!-- For example: | ||||
| | mainnet | | ||||
| | kovan | | ||||
| | testrpc | | ||||
| --> | ||||
| @@ -1,3 +1,36 @@ | ||||
| This PR: | ||||
| <!--- Thank you for taking the time to submit a Pull Request --> | ||||
|  | ||||
| \* | ||||
| <!--- Provide a general summary of the issue in the Title above --> | ||||
|  | ||||
| ## Description | ||||
|  | ||||
| <!--- Describe your changes in detail --> | ||||
|  | ||||
| ## Motivation and Context | ||||
|  | ||||
| <!--- Why is this change required? What problem does it solve? --> | ||||
|  | ||||
| <!--- If it fixes an open issue, please link to the issue here. --> | ||||
|  | ||||
| ## How Has This Been Tested? | ||||
|  | ||||
| <!--- Please describe in detail how you tested your changes. --> | ||||
|  | ||||
| <!--- Include details of your testing environment, and the tests you ran to --> | ||||
|  | ||||
| <!--- see how your change affects other areas of the code, etc. --> | ||||
|  | ||||
| ## Types of changes | ||||
|  | ||||
| <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: | ||||
| - [ ] Bug fix (non-breaking change which fixes an issue) | ||||
| - [ ] New feature (non-breaking change which adds functionality) | ||||
| - [ ] Breaking change (fix or feature that would cause existing functionality to change) | ||||
|  | ||||
| ## Checklist: | ||||
| <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> | ||||
|  | ||||
| <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> | ||||
|  | ||||
| * [ ] Change requires a change to the documentation. | ||||
| * [ ] Added tests to cover my changes. | ||||
|   | ||||
| @@ -40,8 +40,8 @@ This repository contains all the 0x developer tools written in TypeScript. Our h | ||||
| | Package                                                     | Description                                                      | | ||||
| | ----------------------------------------------------------- | ---------------------------------------------------------------- | | ||||
| | [`@0xproject/contracts`](/packages/contracts)               | 0x solidity smart contracts & tests                              | | ||||
| | [`@0xproject/kovan_faucets`](/packages/kovan-faucets)       | A faucet micro-service that dispenses test ERC20 tokens or Ether | | ||||
| | [`@0xproject/monorepo-scripts`](/packages/monorepo-scripts) | Shared monorepo scripts                                          | | ||||
| | [`@0xproject/testnet-faucets`](/packages/testnet-faucets)   | A faucet micro-service that dispenses test ERC20 tokens or Ether | | ||||
| | [`@0xproject/website`](/packages/website)                   | 0x website & Portal DApp                                         | | ||||
|  | ||||
| ## Usage | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
|     "workspaces": ["packages/*"], | ||||
|     "scripts": { | ||||
|         "testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"", | ||||
|         "prettier": "prettier --write '**/*.{ts,tsx,json,md}'", | ||||
|         "prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}'", | ||||
|         "prettier": "prettier --write '**/*.{ts,tsx,json,md}' --config .prettierrc", | ||||
|         "prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}' --config .prettierrc", | ||||
|         "lerna:run": "lerna run", | ||||
|         "lerna:rebuild": "lerna run clean; lerna run build;", | ||||
|         "lerna:publish": | ||||
|   | ||||
| @@ -1,6 +1,22 @@ | ||||
| # CHANGELOG | ||||
|  | ||||
| ## v0.30.1 - _January 18, 2018_ | ||||
| ## v0.31.1 - _February 1, 2018_ | ||||
|  | ||||
|     * Fix the bug causing order watcher to throw is makerToken === zrx (#357) | ||||
|  | ||||
| ## v0.31.0 - _January 30, 2018_ | ||||
|  | ||||
|     * Add the `shouldAddPersonalMessagePrefix` parameter to `signOrderHashAsync` so that the | ||||
|     caller can decide on whether to add the personalMessage prefix before relaying the request | ||||
|     to the signer. Parity Signer, Ledger and TestRPC add the prefix themselves, Metamask expects | ||||
|     it to have already been added. (#349) | ||||
|  | ||||
| ## v0.30.2 - _January 29, 2018_ | ||||
|  | ||||
|     * Add Rinkeby testnet addresses to artifacts  (#337) | ||||
|     * Move @0xproject/types to dependencies from devDependencies fixing missing type errors | ||||
|  | ||||
| ## v0.30.1 - _January 24, 2018_ | ||||
|  | ||||
|     * Fix a bug allowing negative fill values  (#212) | ||||
|     * Fix a bug that made it impossible to pass a custom ZRX address  (#341) | ||||
|   | ||||
| @@ -20,6 +20,6 @@ export class {{contractName}}Contract extends BaseContract { | ||||
| {{/each}} | ||||
|     constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial<TxData>) { | ||||
|         super(web3ContractInstance, defaults); | ||||
|         classUtils.bindAll(this, ['web3ContractInstance', 'defaults']); | ||||
|         classUtils.bindAll(this, ['_web3ContractInstance', '_defaults']); | ||||
|     } | ||||
| } // tslint:disable:max-file-line-count | ||||
| @@ -5,8 +5,8 @@ public {{this.name}} = { | ||||
|     ): Promise<{{> return_type outputs=outputs}}> { | ||||
|         const self = this as {{contractName}}Contract; | ||||
|         const result = await promisify<{{> return_type outputs=outputs}}>( | ||||
|             self.web3ContractInstance.{{this.name}}.call, | ||||
|             self.web3ContractInstance, | ||||
|             self._web3ContractInstance.{{this.name}}.call, | ||||
|             self._web3ContractInstance, | ||||
|         )( | ||||
|             {{> params inputs=inputs}} | ||||
|         ); | ||||
| @@ -9,7 +9,7 @@ public {{this.name}} = { | ||||
|     {{/this.payable}} | ||||
|     ): Promise<string> { | ||||
|         const self = this as {{contractName}}Contract; | ||||
|         const txDataWithDefaults = await self.applyDefaultsToTxDataAsync( | ||||
|         const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( | ||||
|             txData, | ||||
|             self.{{this.name}}.estimateGasAsync.bind( | ||||
|                 self, | ||||
| @@ -17,7 +17,7 @@ public {{this.name}} = { | ||||
|             ), | ||||
|         ); | ||||
|         const txHash = await promisify<string>( | ||||
|             self.web3ContractInstance.{{this.name}}, self.web3ContractInstance, | ||||
|             self._web3ContractInstance.{{this.name}}, self._web3ContractInstance, | ||||
|         )( | ||||
|             {{> params inputs=inputs}} | ||||
|             txDataWithDefaults, | ||||
| @@ -29,11 +29,11 @@ public {{this.name}} = { | ||||
|         txData: TxData = {}, | ||||
|     ): Promise<number> { | ||||
|         const self = this as {{contractName}}Contract; | ||||
|         const txDataWithDefaults = await self.applyDefaultsToTxDataAsync( | ||||
|         const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( | ||||
|             txData, | ||||
|         ); | ||||
|         const gas = await promisify<number>( | ||||
|             self.web3ContractInstance.{{this.name}}.estimateGas, self.web3ContractInstance, | ||||
|             self._web3ContractInstance.{{this.name}}.estimateGas, self._web3ContractInstance, | ||||
|         )( | ||||
|             {{> params inputs=inputs}} | ||||
|             txDataWithDefaults, | ||||
| @@ -45,7 +45,7 @@ public {{this.name}} = { | ||||
|         txData: TxData = {}, | ||||
|     ): string { | ||||
|         const self = this as {{contractName}}Contract; | ||||
|         const abiEncodedTransactionData = self.web3ContractInstance.{{this.name}}.getData(); | ||||
|         const abiEncodedTransactionData = self._web3ContractInstance.{{this.name}}.getData(); | ||||
|         return abiEncodedTransactionData; | ||||
|     }, | ||||
| }; | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "0x.js", | ||||
|     "version": "0.30.0", | ||||
|     "version": "0.31.0", | ||||
|     "description": "A javascript library for interacting with the 0x protocol", | ||||
|     "keywords": ["0x.js", "0xproject", "ethereum", "tokens", "exchange"], | ||||
|     "main": "lib/src/index.js", | ||||
| @@ -12,7 +12,7 @@ | ||||
|         "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", | ||||
|             "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --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", | ||||
| @@ -38,10 +38,9 @@ | ||||
|         "node": ">=6.0.0" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "@0xproject/abi-gen": "^0.1.2", | ||||
|         "@0xproject/dev-utils": "^0.0.5", | ||||
|         "@0xproject/tslint-config": "^0.4.2", | ||||
|         "@0xproject/types": "^0.1.4", | ||||
|         "@0xproject/abi-gen": "^0.1.5", | ||||
|         "@0xproject/dev-utils": "^0.0.8", | ||||
|         "@0xproject/tslint-config": "^0.4.5", | ||||
|         "@types/bintrees": "^1.0.2", | ||||
|         "@types/jsonschema": "^1.1.1", | ||||
|         "@types/lodash": "^4.14.86", | ||||
| @@ -52,7 +51,7 @@ | ||||
|         "awesome-typescript-loader": "^3.1.3", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-as-promised-typescript-typings": "^0.0.4", | ||||
|         "chai-as-promised-typescript-typings": "^0.0.7", | ||||
|         "chai-bignumber": "^2.0.1", | ||||
|         "chai-typescript-typings": "^0.0.2", | ||||
|         "copyfiles": "^1.2.0", | ||||
| @@ -64,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", | ||||
| @@ -73,20 +72,21 @@ | ||||
|         "typedoc": "~0.8.0", | ||||
|         "typescript": "~2.6.1", | ||||
|         "web3-provider-engine": "^13.0.1", | ||||
|         "web3-typescript-typings": "^0.9.4", | ||||
|         "web3-typescript-typings": "^0.9.7", | ||||
|         "webpack": "^3.1.0" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0xproject/assert": "^0.0.11", | ||||
|         "@0xproject/json-schemas": "^0.7.3", | ||||
|         "@0xproject/utils": "^0.2.0", | ||||
|         "@0xproject/web3-wrapper": "^0.1.5", | ||||
|         "@0xproject/assert": "^0.0.14", | ||||
|         "@0xproject/json-schemas": "^0.7.6", | ||||
|         "@0xproject/types": "^0.1.7", | ||||
|         "@0xproject/utils": "^0.2.3", | ||||
|         "@0xproject/web3-wrapper": "^0.1.8", | ||||
|         "bintrees": "^1.0.2", | ||||
|         "bn.js": "^4.11.8", | ||||
|         "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" | ||||
|   | ||||
| @@ -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'; | ||||
| @@ -240,20 +232,22 @@ export class ZeroEx { | ||||
|      * @param   orderHash       Hex encoded orderHash to sign. | ||||
|      * @param   signerAddress   The hex encoded Ethereum address you wish to sign it with. This address | ||||
|      *          must be available via the Web3.Provider supplied to 0x.js. | ||||
|      * @param   shouldAddPersonalMessagePrefix  Some signers add the personal message prefix `\x19Ethereum Signed Message` | ||||
|      *          themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client | ||||
|      *          (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix | ||||
|      *          before sending the request. | ||||
|      * @return  An object containing the Elliptic curve signature parameters generated by signing the orderHash. | ||||
|      */ | ||||
|     public async signOrderHashAsync(orderHash: string, signerAddress: string): Promise<ECSignature> { | ||||
|     public async signOrderHashAsync( | ||||
|         orderHash: string, | ||||
|         signerAddress: string, | ||||
|         shouldAddPersonalMessagePrefix: boolean, | ||||
|     ): Promise<ECSignature> { | ||||
|         assert.isHexString('orderHash', orderHash); | ||||
|         await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper); | ||||
|  | ||||
|         let msgHashHex; | ||||
|         const nodeVersion = await this._web3Wrapper.getNodeVersionAsync(); | ||||
|         const isParityNode = utils.isParityNode(nodeVersion); | ||||
|         const isTestRpc = utils.isTestRpc(nodeVersion); | ||||
|         if (isParityNode || isTestRpc) { | ||||
|             // Parity and TestRpc nodes add the personalMessage prefix itself | ||||
|             msgHashHex = orderHash; | ||||
|         } else { | ||||
|         let msgHashHex = orderHash; | ||||
|         if (shouldAddPersonalMessagePrefix) { | ||||
|             const orderHashBuff = ethUtil.toBuffer(orderHash); | ||||
|             const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff); | ||||
|             msgHashHex = ethUtil.bufferToHex(msgHashBuff); | ||||
| @@ -332,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 | ||||
|   | ||||
| @@ -274,6 +274,9 @@ | ||||
|         "3": { | ||||
|             "address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a" | ||||
|         }, | ||||
|         "4": { | ||||
|             "address": "0xc778417e063141139fce010982780140aa0cd5ab" | ||||
|         }, | ||||
|         "42": { | ||||
|             "address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1" | ||||
|         }, | ||||
|   | ||||
| @@ -597,6 +597,9 @@ | ||||
|         "3": { | ||||
|             "address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac" | ||||
|         }, | ||||
|         "4": { | ||||
|             "address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05" | ||||
|         }, | ||||
|         "42": { | ||||
|             "address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364" | ||||
|         }, | ||||
|   | ||||
| @@ -534,6 +534,9 @@ | ||||
|         "3": { | ||||
|             "address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed" | ||||
|         }, | ||||
|         "4": { | ||||
|             "address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6" | ||||
|         }, | ||||
|         "42": { | ||||
|             "address": "0xf18e504561f4347bea557f3d4558f559dddbae7f" | ||||
|         }, | ||||
|   | ||||
| @@ -174,6 +174,9 @@ | ||||
|         "3": { | ||||
|             "address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6" | ||||
|         }, | ||||
|         "4": { | ||||
|             "address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d" | ||||
|         }, | ||||
|         "42": { | ||||
|             "address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4" | ||||
|         }, | ||||
|   | ||||
| @@ -7,6 +7,9 @@ | ||||
|         "3": { | ||||
|             "address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d" | ||||
|         }, | ||||
|         "4": { | ||||
|             "address": "0x00f58d6d585f84b2d7267940cede30ce2fe6eae8" | ||||
|         }, | ||||
|         "42": { | ||||
|             "address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570" | ||||
|         }, | ||||
|   | ||||
| @@ -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'; | ||||
|  | ||||
| @@ -54,7 +52,7 @@ export class ContractWrapper { | ||||
|         this._onLogAddedSubscriptionToken = undefined; | ||||
|         this._onLogRemovedSubscriptionToken = undefined; | ||||
|     } | ||||
|     protected unsubscribeAll(): void { | ||||
|     protected _unsubscribeAll(): void { | ||||
|         const filterTokens = _.keys(this._filterCallbacks); | ||||
|         _.each(filterTokens, filterToken => { | ||||
|             this._unsubscribe(filterToken); | ||||
|   | ||||
| @@ -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'; | ||||
| @@ -160,11 +159,11 @@ export class EtherTokenWrapper extends ContractWrapper { | ||||
|     /** | ||||
|      * Cancels all existing subscriptions | ||||
|      */ | ||||
|     public unsubscribeAll(): void { | ||||
|         super.unsubscribeAll(); | ||||
|     public _unsubscribeAll(): void { | ||||
|         super._unsubscribeAll(); | ||||
|     } | ||||
|     private _invalidateContractInstance(): void { | ||||
|         this.unsubscribeAll(); | ||||
|         this._unsubscribeAll(); | ||||
|         this._etherTokenContractsByAddress = {}; | ||||
|     } | ||||
|     private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> { | ||||
|   | ||||
| @@ -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'; | ||||
| @@ -680,8 +678,8 @@ export class ExchangeWrapper extends ContractWrapper { | ||||
|     /** | ||||
|      * Cancels all existing subscriptions | ||||
|      */ | ||||
|     public unsubscribeAll(): void { | ||||
|         super.unsubscribeAll(); | ||||
|     public _unsubscribeAll(): void { | ||||
|         super._unsubscribeAll(); | ||||
|     } | ||||
|     /** | ||||
|      * Gets historical logs without creating a subscription | ||||
| @@ -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); | ||||
| @@ -863,7 +861,7 @@ export class ExchangeWrapper extends ContractWrapper { | ||||
|         return contractAddress; | ||||
|     } | ||||
|     private _invalidateContractInstances(): void { | ||||
|         this.unsubscribeAll(); | ||||
|         this._unsubscribeAll(); | ||||
|         delete this._exchangeContractIfExists; | ||||
|     } | ||||
|     private async _isValidSignatureUsingContractCallAsync( | ||||
|   | ||||
| @@ -3,9 +3,9 @@ import * as _ from 'lodash'; | ||||
| import * as Web3 from 'web3'; | ||||
|  | ||||
| export class BaseContract { | ||||
|     protected web3ContractInstance: Web3.ContractInstance; | ||||
|     protected defaults: Partial<TxData>; | ||||
|     protected async applyDefaultsToTxDataAsync<T extends TxData|TxDataPayable>( | ||||
|     protected _web3ContractInstance: Web3.ContractInstance; | ||||
|     protected _defaults: Partial<TxData>; | ||||
|     protected async _applyDefaultsToTxDataAsync<T extends TxData|TxDataPayable>( | ||||
|         txData: T, | ||||
|         estimateGasAsync?: (txData: T) => Promise<number>, | ||||
|     ): Promise<TxData> { | ||||
| @@ -15,7 +15,7 @@ export class BaseContract { | ||||
|         // 3. Gas estimate calculation + safety margin | ||||
|         const removeUndefinedProperties = _.pickBy; | ||||
|         const txDataWithDefaults = { | ||||
|             ...removeUndefinedProperties(this.defaults), | ||||
|             ...removeUndefinedProperties(this._defaults), | ||||
|             ...removeUndefinedProperties(txData as any), | ||||
|             // HACK: TS can't prove that T is spreadable. | ||||
|             // Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged | ||||
| @@ -27,7 +27,7 @@ export class BaseContract { | ||||
|         return txDataWithDefaults; | ||||
|     } | ||||
|     constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial<TxData>) { | ||||
|         this.web3ContractInstance = web3ContractInstance; | ||||
|         this.defaults = defaults; | ||||
|         this._web3ContractInstance = web3ContractInstance; | ||||
|         this._defaults = defaults; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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'; | ||||
|  | ||||
| @@ -343,8 +342,8 @@ export class TokenWrapper extends ContractWrapper { | ||||
|     /** | ||||
|      * Cancels all existing subscriptions | ||||
|      */ | ||||
|     public unsubscribeAll(): void { | ||||
|         super.unsubscribeAll(); | ||||
|     public _unsubscribeAll(): void { | ||||
|         super._unsubscribeAll(); | ||||
|     } | ||||
|     /** | ||||
|      * Gets historical logs without creating a subscription | ||||
| @@ -375,7 +374,7 @@ export class TokenWrapper extends ContractWrapper { | ||||
|         return logs; | ||||
|     } | ||||
|     private _invalidateContractInstances(): void { | ||||
|         this.unsubscribeAll(); | ||||
|         this._unsubscribeAll(); | ||||
|         this._tokenContractsByAddress = {}; | ||||
|     } | ||||
|     private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> { | ||||
|   | ||||
							
								
								
									
										16
									
								
								packages/0x.js/src/globals.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								packages/0x.js/src/globals.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -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[]; | ||||
| } | ||||
|   | ||||
| @@ -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'; | ||||
|   | ||||
| @@ -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'; | ||||
| @@ -134,8 +133,12 @@ export class OrderStateWatcher { | ||||
|         delete this._orderStateByOrderHashCache[orderHash]; | ||||
|         const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper; | ||||
|         const zrxTokenAddress = exchange.getZRXTokenAddress(); | ||||
|  | ||||
|         this._removeFromDependentOrderHashes(signedOrder.maker, zrxTokenAddress, orderHash); | ||||
|         this._removeFromDependentOrderHashes(signedOrder.maker, signedOrder.makerTokenAddress, orderHash); | ||||
|         if (zrxTokenAddress !== signedOrder.makerTokenAddress) { | ||||
|             this._removeFromDependentOrderHashes(signedOrder.maker, signedOrder.makerTokenAddress, orderHash); | ||||
|         } | ||||
|  | ||||
|         this._expirationWatcher.removeOrder(orderHash); | ||||
|     } | ||||
|     /** | ||||
| @@ -224,12 +227,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) { | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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 = { | ||||
|     /** | ||||
| @@ -20,12 +21,6 @@ export const utils = { | ||||
|         // tslint:disable-next-line: no-console | ||||
|         console.log(message); | ||||
|     }, | ||||
|     isParityNode(nodeVersion: string): boolean { | ||||
|         return _.includes(nodeVersion, 'Parity'); | ||||
|     }, | ||||
|     isTestRpc(nodeVersion: string): boolean { | ||||
|         return _.includes(nodeVersion, 'TestRPC'); | ||||
|     }, | ||||
|     spawnSwitchErr(name: string, value: any): Error { | ||||
|         return new Error(`Unexpected switch value: ${value} encountered for ${name}`); | ||||
|     }, | ||||
|   | ||||
| @@ -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,12 +10,13 @@ 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; | ||||
|  | ||||
| const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false; | ||||
|  | ||||
| describe('ZeroEx library', () => { | ||||
|     const web3 = web3Factory.create(); | ||||
|     const config = { | ||||
| @@ -198,7 +199,11 @@ describe('ZeroEx library', () => { | ||||
|                 r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', | ||||
|                 s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', | ||||
|             }; | ||||
|             const ecSignature = await zeroEx.signOrderHashAsync(orderHash, makerAddress); | ||||
|             const ecSignature = await zeroEx.signOrderHashAsync( | ||||
|                 orderHash, | ||||
|                 makerAddress, | ||||
|                 SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, | ||||
|             ); | ||||
|             expect(ecSignature).to.deep.equal(expectedECSignature); | ||||
|         }); | ||||
|         it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => { | ||||
| @@ -215,7 +220,11 @@ describe('ZeroEx library', () => { | ||||
|                 Sinon.stub(ZeroEx, 'isValidSignature').returns(true), | ||||
|             ]; | ||||
|  | ||||
|             const ecSignature = await zeroEx.signOrderHashAsync(orderHash, makerAddress); | ||||
|             const ecSignature = await zeroEx.signOrderHashAsync( | ||||
|                 orderHash, | ||||
|                 makerAddress, | ||||
|                 SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, | ||||
|             ); | ||||
|             expect(ecSignature).to.deep.equal(expectedECSignature); | ||||
|         }); | ||||
|         it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => { | ||||
| @@ -232,7 +241,11 @@ describe('ZeroEx library', () => { | ||||
|                 Sinon.stub(ZeroEx, 'isValidSignature').returns(true), | ||||
|             ]; | ||||
|  | ||||
|             const ecSignature = await zeroEx.signOrderHashAsync(orderHash, makerAddress); | ||||
|             const ecSignature = await zeroEx.signOrderHashAsync( | ||||
|                 orderHash, | ||||
|                 makerAddress, | ||||
|                 SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, | ||||
|             ); | ||||
|             expect(ecSignature).to.deep.equal(expectedECSignature); | ||||
|         }); | ||||
|     }); | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| @@ -145,7 +144,7 @@ describe('EtherTokenWrapper', () => { | ||||
|             etherTokenAddress = etherToken.address; | ||||
|         }); | ||||
|         afterEach(() => { | ||||
|             zeroEx.etherToken.unsubscribeAll(); | ||||
|             zeroEx.etherToken._unsubscribeAll(); | ||||
|         }); | ||||
|         // Hack: Mocha does not allow a test to be both async and have a `done` callback | ||||
|         // Since we need to await the receipt of the event in the `subscribe` callback, | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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'; | ||||
|  | ||||
| @@ -922,7 +921,7 @@ describe('ExchangeWrapper', () => { | ||||
|             ); | ||||
|         }); | ||||
|         afterEach(async () => { | ||||
|             zeroEx.exchange.unsubscribeAll(); | ||||
|             zeroEx.exchange._unsubscribeAll(); | ||||
|         }); | ||||
|         // Hack: Mocha does not allow a test to be both async and have a `done` callback | ||||
|         // Since we need to await the receipt of the event in the `subscribe` callback, | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
| @@ -50,7 +49,7 @@ describe('SubscriptionTest', () => { | ||||
|             tokenAddress = token.address; | ||||
|         }); | ||||
|         afterEach(() => { | ||||
|             zeroEx.token.unsubscribeAll(); | ||||
|             zeroEx.token._unsubscribeAll(); | ||||
|             _.each(stubs, s => s.restore()); | ||||
|             stubs = []; | ||||
|         }); | ||||
| @@ -77,7 +76,7 @@ describe('SubscriptionTest', () => { | ||||
|                 const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop; | ||||
|                 zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); | ||||
|                 stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))]; | ||||
|                 zeroEx.token.unsubscribeAll(); | ||||
|                 zeroEx.token._unsubscribeAll(); | ||||
|                 done(); | ||||
|             })().catch(done); | ||||
|         }); | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
| @@ -378,7 +377,7 @@ describe('TokenWrapper', () => { | ||||
|             tokenAddress = token.address; | ||||
|         }); | ||||
|         afterEach(() => { | ||||
|             zeroEx.token.unsubscribeAll(); | ||||
|             zeroEx.token._unsubscribeAll(); | ||||
|         }); | ||||
|         // Hack: Mocha does not allow a test to be both async and have a `done` callback | ||||
|         // Since we need to await the receipt of the event in the `subscribe` callback, | ||||
|   | ||||
| @@ -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, | ||||
| }; | ||||
|   | ||||
| @@ -3,6 +3,8 @@ import * as _ from 'lodash'; | ||||
|  | ||||
| import { SignedOrder, ZeroEx } from '../../src'; | ||||
|  | ||||
| const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false; | ||||
|  | ||||
| export const orderFactory = { | ||||
|     async createSignedOrderAsync( | ||||
|         zeroEx: ZeroEx, | ||||
| @@ -37,7 +39,7 @@ export const orderFactory = { | ||||
|             expirationUnixTimestampSec, | ||||
|         }; | ||||
|         const orderHash = ZeroEx.getOrderHashHex(order); | ||||
|         const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker); | ||||
|         const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX); | ||||
|         const signedOrder: SignedOrder = _.assign(order, { ecSignature }); | ||||
|         return signedOrder; | ||||
|     }, | ||||
|   | ||||
| @@ -1,5 +1,9 @@ | ||||
| # CHANGELOG | ||||
|  | ||||
| ## v0.2.0 - _???_ | ||||
|  | ||||
| * Added CLI options for explicit specifying location of partials and main template (#346) | ||||
|  | ||||
| ## v0.1.0 - _January 11, 2018_ | ||||
|  | ||||
| * Fixed array typings with union types (#295) | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0xproject/abi-gen", | ||||
|     "version": "0.1.2", | ||||
|     "version": "0.1.5", | ||||
|     "description": "Generate contract wrappers from ABI and handlebars templates", | ||||
|     "main": "lib/index.js", | ||||
|     "types": "lib/index.d.ts", | ||||
| @@ -22,7 +22,7 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md", | ||||
|     "dependencies": { | ||||
|         "@0xproject/utils": "^0.2.0", | ||||
|         "@0xproject/utils": "^0.2.3", | ||||
|         "chalk": "^2.3.0", | ||||
|         "glob": "^7.1.2", | ||||
|         "handlebars": "^4.0.11", | ||||
| @@ -33,7 +33,7 @@ | ||||
|         "yargs": "^10.0.3" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "@0xproject/tslint-config": "^0.4.2", | ||||
|         "@0xproject/tslint-config": "^0.4.5", | ||||
|         "@types/glob": "^5.0.33", | ||||
|         "@types/handlebars": "^4.0.36", | ||||
|         "@types/mkdirp": "^0.5.1", | ||||
| @@ -43,6 +43,6 @@ | ||||
|         "shx": "^0.2.2", | ||||
|         "tslint": "5.8.0", | ||||
|         "typescript": "~2.6.1", | ||||
|         "web3-typescript-typings": "^0.9.4" | ||||
|         "web3-typescript-typings": "^0.9.7" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -17,24 +17,45 @@ import { utils } from './utils'; | ||||
| const ABI_TYPE_CONSTRUCTOR = 'constructor'; | ||||
| const ABI_TYPE_METHOD = 'function'; | ||||
| const ABI_TYPE_EVENT = 'event'; | ||||
| const MAIN_TEMPLATE_NAME = 'contract.mustache'; | ||||
|  | ||||
| const args = yargs | ||||
|     .option('abiGlob', { | ||||
|     .option('abis', { | ||||
|         describe: 'Glob pattern to search for ABI JSON files', | ||||
|         type: 'string', | ||||
|         demand: true, | ||||
|     }) | ||||
|     .option('templates', { | ||||
|         describe: 'Folder where to search for templates', | ||||
|         type: 'string', | ||||
|         demand: true, | ||||
|         demandOption: true, | ||||
|     }) | ||||
|     .option('output', { | ||||
|         alias: ['o', 'out'], | ||||
|         describe: 'Folder where to put the output files', | ||||
|         type: 'string', | ||||
|         demand: true, | ||||
|     }).argv; | ||||
|         normalize: true, | ||||
|         demandOption: true, | ||||
|     }) | ||||
|     .option('partials', { | ||||
|         describe: 'Glob pattern for the partial template files', | ||||
|         type: 'string', | ||||
|         implies: 'template', | ||||
|     }) | ||||
|     .option('template', { | ||||
|         describe: 'Path for the main template file that will be used to generate each contract', | ||||
|         type: 'string', | ||||
|         demandOption: true, | ||||
|         normalize: true, | ||||
|     }) | ||||
|     .example( | ||||
|         "$0 --abis 'src/artifacts/**/*.json' --out 'src/contracts/generated/' --partials 'src/templates/partials/**/*.handlebars' --template 'src/templates/contract.handlebars'", | ||||
|         'Full usage example', | ||||
|     ).argv; | ||||
|  | ||||
| function registerPartials(partialsGlob: string) { | ||||
|     const partialTemplateFileNames = globSync(partialsGlob); | ||||
|     utils.log(`Found ${chalk.green(`${partialTemplateFileNames.length}`)} ${chalk.bold('partial')} templates`); | ||||
|     for (const partialTemplateFileName of partialTemplateFileNames) { | ||||
|         const namedContent = utils.getNamedContent(partialTemplateFileName); | ||||
|         Handlebars.registerPartial(namedContent.name, namedContent.content); | ||||
|     } | ||||
|     return partialsGlob; | ||||
| } | ||||
|  | ||||
| function writeOutputFile(name: string, renderedTsCode: string): void { | ||||
|     const fileName = toSnakeCase(name); | ||||
| @@ -45,15 +66,14 @@ function writeOutputFile(name: string, renderedTsCode: string): void { | ||||
|  | ||||
| Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input)); | ||||
| Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output)); | ||||
| const partialTemplateFileNames = globSync(`${args.templates}/partials/**/*.mustache`); | ||||
| for (const partialTemplateFileName of partialTemplateFileNames) { | ||||
|     const namedContent = utils.getNamedContent(partialTemplateFileName); | ||||
|     Handlebars.registerPartial(namedContent.name, namedContent.content); | ||||
| } | ||||
|  | ||||
| const mainTemplate = utils.getNamedContent(`${args.templates}/${MAIN_TEMPLATE_NAME}`); | ||||
| if (args.partials) { | ||||
|     registerPartials(args.partials); | ||||
| } | ||||
| const mainTemplate = utils.getNamedContent(args.template); | ||||
| const template = Handlebars.compile<ContextData>(mainTemplate.content); | ||||
| const abiFileNames = globSync(args.abiGlob); | ||||
| const abiFileNames = globSync(args.abis); | ||||
|  | ||||
| if (_.isEmpty(abiFileNames)) { | ||||
|     utils.log(`${chalk.red(`No ABI files found.`)}`); | ||||
|     utils.log(`Please make sure you've passed the correct folder name and that the files have | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0xproject/assert", | ||||
|     "version": "0.0.11", | ||||
|     "version": "0.0.14", | ||||
|     "description": "Provides a standard way of performing type and schema validation across 0x projects", | ||||
|     "main": "lib/src/index.js", | ||||
|     "types": "lib/src/index.d.ts", | ||||
| @@ -23,7 +23,7 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0xproject/tslint-config": "^0.4.2", | ||||
|         "@0xproject/tslint-config": "^0.4.5", | ||||
|         "@types/lodash": "^4.14.86", | ||||
|         "@types/mocha": "^2.2.42", | ||||
|         "@types/valid-url": "^1.0.2", | ||||
| @@ -37,8 +37,8 @@ | ||||
|         "typescript": "~2.6.1" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0xproject/json-schemas": "^0.7.3", | ||||
|         "@0xproject/utils": "^0.2.0", | ||||
|         "@0xproject/json-schemas": "^0.7.6", | ||||
|         "@0xproject/utils": "^0.2.3", | ||||
|         "lodash": "^4.17.4", | ||||
|         "valid-url": "^1.0.9" | ||||
|     } | ||||
|   | ||||
| @@ -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" | ||||
|     ] | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "chai-as-promised-typescript-typings", | ||||
|     "version": "0.0.4", | ||||
|     "version": "0.0.7", | ||||
|     "description": "Typescript type definitions for chai-as-promised", | ||||
|     "main": "index.d.ts", | ||||
|     "types": "index.d.ts", | ||||
| @@ -16,6 +16,6 @@ | ||||
|     }, | ||||
|     "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" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0xproject/connect", | ||||
|     "version": "0.5.0", | ||||
|     "version": "0.5.3", | ||||
|     "description": "A javascript library for interacting with the standard relayer api", | ||||
|     "keywords": ["connect", "0xproject", "ethereum", "tokens", "exchange"], | ||||
|     "main": "lib/src/index.js", | ||||
| @@ -31,16 +31,16 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md", | ||||
|     "dependencies": { | ||||
|         "@0xproject/assert": "^0.0.11", | ||||
|         "@0xproject/json-schemas": "^0.7.3", | ||||
|         "@0xproject/utils": "^0.2.0", | ||||
|         "@0xproject/assert": "^0.0.14", | ||||
|         "@0xproject/json-schemas": "^0.7.6", | ||||
|         "@0xproject/utils": "^0.2.3", | ||||
|         "isomorphic-fetch": "^2.2.1", | ||||
|         "lodash": "^4.17.4", | ||||
|         "query-string": "^5.0.1", | ||||
|         "websocket": "^1.0.25" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "@0xproject/tslint-config": "^0.4.2", | ||||
|         "@0xproject/tslint-config": "^0.4.5", | ||||
|         "@types/fetch-mock": "^5.12.1", | ||||
|         "@types/lodash": "^4.14.86", | ||||
|         "@types/mocha": "^2.2.42", | ||||
| @@ -48,7 +48,7 @@ | ||||
|         "@types/websocket": "^0.0.34", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-as-promised-typescript-typings": "^0.0.4", | ||||
|         "chai-as-promised-typescript-typings": "^0.0.7", | ||||
|         "chai-typescript-typings": "^0.0.2", | ||||
|         "copyfiles": "^1.2.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
| @@ -59,6 +59,6 @@ | ||||
|         "tslint": "5.8.0", | ||||
|         "typedoc": "~0.8.0", | ||||
|         "typescript": "~2.6.1", | ||||
|         "web3-typescript-typings": "^0.9.4" | ||||
|         "web3-typescript-typings": "^0.9.7" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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" | ||||
|     ] | ||||
|   | ||||
| @@ -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 | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								packages/contracts/globals.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								packages/contracts/globals.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -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; | ||||
|   | ||||
| @@ -1,6 +0,0 @@ | ||||
| import { Artifacts } from '../util/artifacts'; | ||||
| const { Migrations } = new Artifacts(artifacts); | ||||
|  | ||||
| module.exports = (deployer: any) => { | ||||
|     deployer.deploy(Migrations); | ||||
| }; | ||||
| @@ -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, | ||||
|         ]); | ||||
|     } | ||||
| }; | ||||
| @@ -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, | ||||
|                 ); | ||||
|             } | ||||
|         }); | ||||
| }; | ||||
| @@ -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); | ||||
|         }); | ||||
| }; | ||||
| @@ -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); | ||||
|                 }); | ||||
|         }); | ||||
|     } | ||||
| }; | ||||
| @@ -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, | ||||
|     }, | ||||
| }; | ||||
| @@ -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, | ||||
|         }, | ||||
|     ], | ||||
| }; | ||||
| @@ -1,16 +1,18 @@ | ||||
| { | ||||
|     "private": true, | ||||
|     "name": "contracts", | ||||
|     "version": "2.1.4", | ||||
|     "version": "2.1.7", | ||||
|     "description": "Smart contract components of 0x protocol", | ||||
|     "main": "index.js", | ||||
|     "directories": { | ||||
|         "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", | ||||
|         "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", | ||||
| @@ -30,9 +32,9 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x.js/packages/contracts/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0xproject/dev-utils": "^0.0.5", | ||||
|         "@0xproject/tslint-config": "^0.4.2", | ||||
|         "@0xproject/types": "^0.1.4", | ||||
|         "@0xproject/dev-utils": "^0.0.8", | ||||
|         "@0xproject/tslint-config": "^0.4.5", | ||||
|         "@0xproject/types": "^0.1.7", | ||||
|         "@types/bluebird": "^3.5.3", | ||||
|         "@types/lodash": "^4.14.86", | ||||
|         "@types/node": "^8.0.53", | ||||
| @@ -40,27 +42,27 @@ | ||||
|         "@types/yargs": "^10.0.0", | ||||
|         "chai": "^4.0.1", | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-as-promised-typescript-typings": "^0.0.4", | ||||
|         "chai-as-promised-typescript-typings": "^0.0.7", | ||||
|         "chai-bignumber": "^2.0.1", | ||||
|         "chai-typescript-typings": "^0.0.2", | ||||
|         "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.4", | ||||
|         "web3-typescript-typings": "^0.9.7", | ||||
|         "yargs": "^10.0.3" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "0x.js": "^0.30.0", | ||||
|         "@0xproject/deployer": "*", | ||||
|         "@0xproject/json-schemas": "^0.7.3", | ||||
|         "@0xproject/utils": "^0.2.0", | ||||
|         "@0xproject/web3-wrapper": "^0.1.5", | ||||
|         "0x.js": "^0.31.0", | ||||
|         "@0xproject/deployer": "^0.0.4", | ||||
|         "@0xproject/json-schemas": "^0.7.6", | ||||
|         "@0xproject/utils": "^0.2.3", | ||||
|         "@0xproject/web3-wrapper": "^0.1.8", | ||||
|         "bluebird": "^3.5.0", | ||||
|         "bn.js": "^4.11.8", | ||||
|         "ethereumjs-abi": "^0.6.4", | ||||
|   | ||||
| @@ -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))); | ||||
| @@ -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); | ||||
|         }); | ||||
|     }); | ||||
| @@ -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); | ||||
|     }); | ||||
| 
 | ||||
|     beforeEach(async () => { | ||||
|         orderFactory = new OrderFactory(web3Wrapper, defaultOrderParams); | ||||
|         order = await orderFactory.newSignedOrderAsync(); | ||||
|     }); | ||||
| 
 | ||||
|     beforeEach(async () => { | ||||
|         await blockchainLifecycle.startAsync(); | ||||
|     }); | ||||
|     afterEach(async () => { | ||||
|         await blockchainLifecycle.revertAsync(); | ||||
|     }); | ||||
|     describe('getOrderHash', () => { | ||||
|         it('should output the correct orderHash', async () => { | ||||
|             const orderHashHex = await exchangeWrapper.getOrderHashAsync(order); | ||||
| @@ -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 * as Web3 from 'web3'; | ||||
| 
 | ||||
| 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 { 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(); | ||||
							
								
								
									
										191
									
								
								packages/contracts/test/multi_sig_with_time_lock.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								packages/contracts/test/multi_sig_with_time_lock.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -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, | ||||
|             ); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -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; | ||||
| const web3 = web3Factory.create(); | ||||
| const web3Wrapper = new Web3Wrapper(web3.currentProvider); | ||||
| const blockchainLifecycle = new BlockchainLifecycle(); | ||||
| 
 | ||||
| contract('TokenRegistry', (accounts: string[]) => { | ||||
|     const owner = accounts[0]; | ||||
|     const notOwner = accounts[1]; | ||||
| 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); | ||||
|             }); | ||||
| @@ -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); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -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 () => { | ||||
| @@ -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); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -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); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -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; | ||||
| @@ -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); | ||||
							
								
								
									
										16
									
								
								packages/contracts/test/utils/deployer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								packages/contracts/test/utils/deployer.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||
| @@ -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); | ||||
| @@ -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", | ||||
| }; | ||||
| @@ -4,8 +4,6 @@ | ||||
|         "outDir": "lib", | ||||
|         "baseUrl": ".", | ||||
|         "declaration": false, | ||||
|         "strictNullChecks": false, | ||||
|         "strictFunctionTypes": false, | ||||
|         "allowJs": true | ||||
|     }, | ||||
|     "include": [ | ||||
|   | ||||
| @@ -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, | ||||
| }; | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   | ||||
| @@ -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; | ||||
|     }, | ||||
|   | ||||
| @@ -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( | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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; | ||||
|         }; | ||||
|     }; | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| { | ||||
|     "name": "@0xproject/deployer", | ||||
|     "version": "0.0.1", | ||||
|     "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,17 +28,18 @@ | ||||
|     "homepage": "https://github.com/0xProject/0x.js/packages/deployer/README.md", | ||||
|     "devDependencies": { | ||||
|         "copyfiles": "^1.2.0", | ||||
|         "web3-typescript-typings": "^0.9.3", | ||||
|         "web3-typescript-typings": "^0.9.4", | ||||
|         "types-bn": "^0.0.1", | ||||
|         "typescript": "~2.6.1" | ||||
|         "typescript": "~2.6.1", | ||||
|         "web3-typescript-typings": "^0.9.7" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0xproject/utils": "^0.1.3", | ||||
|         "@0xproject/web3-wrapper": "^0.1.4", | ||||
|         "@0xproject/utils": "^0.2.1", | ||||
|         "@0xproject/web3-wrapper": "^0.1.8", | ||||
|         "lodash": "^4.17.4", | ||||
|         "solc": "^0.4.18", | ||||
|         "yargs": "^10.0.3", | ||||
|         "web3": "^0.20.0", | ||||
|         "web3-eth-abi": "^1.0.0-beta.24", | ||||
|         "web3": "^0.20.0" | ||||
|         "yargs": "^10.0.3" | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								packages/deployer/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/deployer/src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| export { Deployer } from './deployer'; | ||||
| @@ -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); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0xproject/dev-utils", | ||||
|     "version": "0.0.5", | ||||
|     "version": "0.0.8", | ||||
|     "description": "0x dev TS utils", | ||||
|     "main": "lib/index.js", | ||||
|     "types": "lib/index.d.ts", | ||||
| @@ -19,19 +19,22 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/0x.js/packages/dev-utils/README.md", | ||||
|     "devDependencies": { | ||||
|         "@0xproject/tslint-config": "^0.4.2", | ||||
|         "@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.0", | ||||
|         "@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" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										5
									
								
								packages/dev-utils/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/dev-utils/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| export const constants = { | ||||
|     RPC_URL: 'http://localhost:8545', | ||||
|     RPC_PORT: 8545, | ||||
|     GAS_ESTIMATE: 1000000, | ||||
| }; | ||||
							
								
								
									
										2
									
								
								packages/dev-utils/src/globals.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								packages/dev-utils/src/globals.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| declare module 'web3-provider-engine'; | ||||
| declare module 'web3-provider-engine/subproviders/rpc'; | ||||
| @@ -1,2 +1,4 @@ | ||||
| export { RPC } from './rpc'; | ||||
| export { BlockchainLifecycle } from './blockchain_lifecycle'; | ||||
| export { web3Factory } from './web3_factory'; | ||||
| export { constants as devConstants } from './constants'; | ||||
|   | ||||
| @@ -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> { | ||||
|   | ||||
| @@ -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 | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user