From c4ee2d73865a1444c079b9e2836b7630a0adf03e Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 12 Nov 2017 22:17:18 -0500 Subject: Switch over to Lerna + Yarn Workspaces setup for a mono-repo approach --- src/0x.ts | 333 ------ src/artifacts.ts | 14 - src/artifacts/EtherToken.json | 445 ------- src/artifacts/Exchange.json | 1130 ------------------ src/artifacts/Token.json | 176 --- src/artifacts/TokenRegistry.json | 1211 -------------------- src/artifacts/TokenTransferProxy.json | 174 --- src/bignumber_config.ts | 11 - src/contract.ts | 80 -- src/contract_wrappers/contract_wrapper.ts | 152 --- src/contract_wrappers/ether_token_wrapper.ts | 87 -- src/contract_wrappers/exchange_wrapper.ts | 866 -------------- src/contract_wrappers/token_registry_wrapper.ts | 122 -- .../token_transfer_proxy_wrapper.ts | 60 - src/contract_wrappers/token_wrapper.ts | 313 ----- src/globals.d.ts | 80 -- src/globalsAugment.d.ts | 23 - src/index.ts | 45 - src/order_watcher/event_watcher.ts | 88 -- src/order_watcher/order_state_watcher.ts | 232 ---- src/schemas/zero_ex_config_schema.ts | 23 - src/stores/balance_proxy_allowance_lazy_store.ts | 82 -- src/stores/order_filled_cancelled_lazy_store.ts | 61 - src/subproviders/empty_wallet_subprovider.ts | 24 - src/types.ts | 525 --------- src/utils/abi_decoder.ts | 68 -- src/utils/assert.ts | 101 -- src/utils/constants.ts | 11 - src/utils/decorators.ts | 35 - src/utils/exchange_transfer_simulator.ts | 88 -- src/utils/filter_utils.ts | 82 -- src/utils/interval_utils.ts | 20 - src/utils/order_state_utils.ts | 119 -- src/utils/order_validation_utils.ts | 166 --- src/utils/signature_utils.ts | 44 - src/utils/utils.ts | 55 - src/web3_wrapper.ts | 172 --- 37 files changed, 7318 deletions(-) delete mode 100644 src/0x.ts delete mode 100644 src/artifacts.ts delete mode 100644 src/artifacts/EtherToken.json delete mode 100644 src/artifacts/Exchange.json delete mode 100644 src/artifacts/Token.json delete mode 100644 src/artifacts/TokenRegistry.json delete mode 100644 src/artifacts/TokenTransferProxy.json delete mode 100644 src/bignumber_config.ts delete mode 100644 src/contract.ts delete mode 100644 src/contract_wrappers/contract_wrapper.ts delete mode 100644 src/contract_wrappers/ether_token_wrapper.ts delete mode 100644 src/contract_wrappers/exchange_wrapper.ts delete mode 100644 src/contract_wrappers/token_registry_wrapper.ts delete mode 100644 src/contract_wrappers/token_transfer_proxy_wrapper.ts delete mode 100644 src/contract_wrappers/token_wrapper.ts delete mode 100644 src/globals.d.ts delete mode 100644 src/globalsAugment.d.ts delete mode 100644 src/index.ts delete mode 100644 src/order_watcher/event_watcher.ts delete mode 100644 src/order_watcher/order_state_watcher.ts delete mode 100644 src/schemas/zero_ex_config_schema.ts delete mode 100644 src/stores/balance_proxy_allowance_lazy_store.ts delete mode 100644 src/stores/order_filled_cancelled_lazy_store.ts delete mode 100644 src/subproviders/empty_wallet_subprovider.ts delete mode 100644 src/types.ts delete mode 100644 src/utils/abi_decoder.ts delete mode 100644 src/utils/assert.ts delete mode 100644 src/utils/constants.ts delete mode 100644 src/utils/decorators.ts delete mode 100644 src/utils/exchange_transfer_simulator.ts delete mode 100644 src/utils/filter_utils.ts delete mode 100644 src/utils/interval_utils.ts delete mode 100644 src/utils/order_state_utils.ts delete mode 100644 src/utils/order_validation_utils.ts delete mode 100644 src/utils/signature_utils.ts delete mode 100644 src/utils/utils.ts delete mode 100644 src/web3_wrapper.ts (limited to 'src') diff --git a/src/0x.ts b/src/0x.ts deleted file mode 100644 index fe765bbbe..000000000 --- a/src/0x.ts +++ /dev/null @@ -1,333 +0,0 @@ -import * as _ from 'lodash'; -import BigNumber from 'bignumber.js'; -import {SchemaValidator, schemas} from '0x-json-schemas'; -import {bigNumberConfigs} from './bignumber_config'; -import * as ethUtil from 'ethereumjs-util'; -import {Web3Wrapper} from './web3_wrapper'; -import {constants} from './utils/constants'; -import {utils} from './utils/utils'; -import {signatureUtils} from './utils/signature_utils'; -import {assert} from './utils/assert'; -import {AbiDecoder} from './utils/abi_decoder'; -import {intervalUtils} from './utils/interval_utils'; -import {artifacts} from './artifacts'; -import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper'; -import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper'; -import {EtherTokenWrapper} from './contract_wrappers/ether_token_wrapper'; -import {TokenWrapper} from './contract_wrappers/token_wrapper'; -import {TokenTransferProxyWrapper} from './contract_wrappers/token_transfer_proxy_wrapper'; -import {OrderStateWatcher} from './order_watcher/order_state_watcher'; -import {OrderStateUtils} from './utils/order_state_utils'; -import { - ECSignature, - ZeroExError, - Order, - SignedOrder, - Web3Provider, - ZeroExConfig, - OrderStateWatcherConfig, - TransactionReceiptWithDecodedLogs, -} from './types'; -import {zeroExConfigSchema} from './schemas/zero_ex_config_schema'; - -// Customize our BigNumber instances -bigNumberConfigs.configure(); - -/** - * The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality - * and all calls to the library should be made through a ZeroEx instance. - */ -export class ZeroEx { - /** - * When creating an order without a specified taker or feeRecipient you must supply the Solidity - * address null type (as opposed to Javascripts `null`, `undefined` or empty string). We expose - * this constant for your convenience. - */ - public static NULL_ADDRESS = constants.NULL_ADDRESS; - - /** - * An instance of the ExchangeWrapper class containing methods for interacting with the 0x Exchange smart contract. - */ - public exchange: ExchangeWrapper; - /** - * An instance of the TokenRegistryWrapper class containing methods for interacting with the 0x - * TokenRegistry smart contract. - */ - public tokenRegistry: TokenRegistryWrapper; - /** - * An instance of the TokenWrapper class containing methods for interacting with any ERC20 token smart contract. - */ - public token: TokenWrapper; - /** - * An instance of the EtherTokenWrapper class containing methods for interacting with the - * wrapped ETH ERC20 token smart contract. - */ - public etherToken: EtherTokenWrapper; - /** - * An instance of the TokenTransferProxyWrapper class containing methods for interacting with the - * tokenTransferProxy smart contract. - */ - public proxy: TokenTransferProxyWrapper; - /** - * An instance of the OrderStateWatcher class containing methods for watching a set of orders for relevant - * blockchain state changes. - */ - public orderStateWatcher: OrderStateWatcher; - private _web3Wrapper: Web3Wrapper; - private _abiDecoder: AbiDecoder; - /** - * Verifies that the elliptic curve signature `signature` was generated - * by signing `data` with the private key corresponding to the `signerAddress` address. - * @param data The hex encoded data signed by the supplied signature. - * @param signature An object containing the elliptic curve signature parameters. - * @param signerAddress The hex encoded address that signed the data, producing the supplied signature. - * @return Whether the signature is valid for the supplied signerAddress and data. - */ - public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean { - assert.isHexString('data', data); - assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema); - assert.isETHAddressHex('signerAddress', signerAddress); - - const isValidSignature = signatureUtils.isValidSignature(data, signature, signerAddress); - return isValidSignature; - } - /** - * Generates a pseudo-random 256-bit salt. - * The salt can be included in an 0x order, ensuring that the order generates a unique orderHash - * and will not collide with other outstanding orders that are identical in all other parameters. - * @return A pseudo-random 256-bit number that can be used as a salt. - */ - public static generatePseudoRandomSalt(): BigNumber { - // BigNumber.random returns a pseudo-random number between 0 & 1 with a passed in number of decimal places. - // Source: https://mikemcl.github.io/bignumber.js/#random - const randomNumber = BigNumber.random(constants.MAX_DIGITS_IN_UNSIGNED_256_INT); - const factor = new BigNumber(10).pow(constants.MAX_DIGITS_IN_UNSIGNED_256_INT - 1); - const salt = randomNumber.times(factor).round(); - return salt; - } - /** - * Checks if the supplied hex encoded order hash is valid. - * Note: Valid means it has the expected format, not that an order with the orderHash exists. - * Use this method when processing orderHashes submitted as user input. - * @param orderHash Hex encoded orderHash. - * @return Whether the supplied orderHash has the expected format. - */ - public static isValidOrderHash(orderHash: string): boolean { - // Since this method can be called to check if any arbitrary string conforms to an orderHash's - // format, we only assert that we were indeed passed a string. - assert.isString('orderHash', orderHash); - const schemaValidator = new SchemaValidator(); - const isValidOrderHash = schemaValidator.validate(orderHash, schemas.orderHashSchema).valid; - return isValidOrderHash; - } - /** - * A unit amount is defined as the amount of a token above the specified decimal places (integer part). - * E.g: If a currency has 18 decimal places, 1e18 or one quintillion of the currency is equivalent - * to 1 unit. - * @param amount The amount in baseUnits that you would like converted to units. - * @param decimals The number of decimal places the unit amount has. - * @return The amount in units. - */ - public static toUnitAmount(amount: BigNumber, decimals: number): BigNumber { - assert.isBigNumber('amount', amount); - assert.isNumber('decimals', decimals); - - const aUnit = new BigNumber(10).pow(decimals); - const unit = amount.div(aUnit); - return unit; - } - /** - * A baseUnit is defined as the smallest denomination of a token. An amount expressed in baseUnits - * is the amount expressed in the smallest denomination. - * E.g: 1 unit of a token with 18 decimal places is expressed in baseUnits as 1000000000000000000 - * @param amount The amount of units that you would like converted to baseUnits. - * @param decimals The number of decimal places the unit amount has. - * @return The amount in baseUnits. - */ - public static toBaseUnitAmount(amount: BigNumber, decimals: number): BigNumber { - assert.isBigNumber('amount', amount); - assert.isNumber('decimals', decimals); - - const unit = new BigNumber(10).pow(decimals); - const baseUnitAmount = amount.times(unit); - return baseUnitAmount; - } - /** - * Computes the orderHash for a supplied order. - * @param order An object that conforms to the Order or SignedOrder interface definitions. - * @return The resulting orderHash from hashing the supplied order. - */ - public static getOrderHashHex(order: Order|SignedOrder): string { - assert.doesConformToSchema('order', order, schemas.orderSchema); - const orderHashHex = utils.getOrderHashHex(order); - return orderHashHex; - } - /** - * Instantiates a new ZeroEx instance that provides the public interface to the 0x.js library. - * @param provider The Web3.js Provider instance you would like the 0x.js library to use for interacting with - * the Ethereum network. - * @param config The configuration object. Look up the type for the description. - * @return An instance of the 0x.js ZeroEx class. - */ - constructor(provider: Web3Provider, config?: ZeroExConfig) { - assert.isWeb3Provider('provider', provider); - if (!_.isUndefined(config)) { - assert.doesConformToSchema('config', config, zeroExConfigSchema); - } - const artifactJSONs = _.values(artifacts); - const abiArrays = _.map(artifactJSONs, artifact => artifact.abi); - this._abiDecoder = new AbiDecoder(abiArrays); - const gasPrice = _.isUndefined(config) ? undefined : config.gasPrice; - const defaults = { - gasPrice, - }; - this._web3Wrapper = new Web3Wrapper(provider, defaults); - this.token = new TokenWrapper( - this._web3Wrapper, - this._abiDecoder, - this._getTokenTransferProxyAddressAsync.bind(this), - ); - const exchageContractAddressIfExists = _.isUndefined(config) ? undefined : config.exchangeContractAddress; - this.exchange = new ExchangeWrapper( - this._web3Wrapper, - this._abiDecoder, - this.token, - exchageContractAddressIfExists, - ); - this.proxy = new TokenTransferProxyWrapper( - this._web3Wrapper, - this._getTokenTransferProxyAddressAsync.bind(this), - ); - const tokenRegistryContractAddressIfExists = _.isUndefined(config) ? - undefined : - config.tokenRegistryContractAddress; - this.tokenRegistry = new TokenRegistryWrapper(this._web3Wrapper, tokenRegistryContractAddressIfExists); - const etherTokenContractAddressIfExists = _.isUndefined(config) ? undefined : config.etherTokenContractAddress; - this.etherToken = new EtherTokenWrapper(this._web3Wrapper, this.token, etherTokenContractAddressIfExists); - const orderWatcherConfig = _.isUndefined(config) ? undefined : config.orderWatcherConfig; - this.orderStateWatcher = new OrderStateWatcher( - this._web3Wrapper, this._abiDecoder, this.token, this.exchange, orderWatcherConfig, - ); - } - /** - * Sets a new web3 provider for 0x.js. Updating the provider will stop all - * subscriptions so you will need to re-subscribe to all events relevant to your app after this call. - * @param provider The Web3Provider you would like the 0x.js library to use from now on. - */ - public async setProviderAsync(provider: Web3Provider) { - this._web3Wrapper.setProvider(provider); - await (this.exchange as any)._invalidateContractInstancesAsync(); - (this.tokenRegistry as any)._invalidateContractInstance(); - await (this.token as any)._invalidateContractInstancesAsync(); - (this.proxy as any)._invalidateContractInstance(); - (this.etherToken as any)._invalidateContractInstance(); - } - /** - * Get user Ethereum addresses available through the supplied web3 provider available for sending transactions. - * @return An array of available user Ethereum addresses. - */ - public async getAvailableAddressesAsync(): Promise { - const availableAddresses = await this._web3Wrapper.getAvailableAddressesAsync(); - return availableAddresses; - } - /** - * Signs an orderHash and returns it's elliptic curve signature. - * This method currently supports TestRPC, Geth and Parity above and below V1.6.6 - * @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. - * @return An object containing the Elliptic curve signature parameters generated by signing the orderHash. - */ - public async signOrderHashAsync(orderHash: string, signerAddress: string): Promise { - 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 { - const orderHashBuff = ethUtil.toBuffer(orderHash); - const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff); - msgHashHex = ethUtil.bufferToHex(msgHashBuff); - } - - const signature = await this._web3Wrapper.signTransactionAsync(signerAddress, msgHashHex); - - // HACK: There is no consensus on whether the signatureHex string should be formatted as - // v + r + s OR r + s + v, and different clients (even different versions of the same client) - // return the signature params in different orders. In order to support all client implementations, - // we parse the signature in both ways, and evaluate if either one is a valid signature. - const validVParamValues = [27, 28]; - const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature); - if (_.includes(validVParamValues, ecSignatureVRS.v)) { - const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, signerAddress); - if (isValidVRSSignature) { - return ecSignatureVRS; - } - } - - const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature); - if (_.includes(validVParamValues, ecSignatureRSV.v)) { - const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, signerAddress); - if (isValidRSVSignature) { - return ecSignatureRSV; - } - } - - throw new Error(ZeroExError.InvalidSignature); - } - /** - * Waits for a transaction to be mined and returns the transaction receipt. - * @param txHash Transaction hash - * @param pollingIntervalMs How often (in ms) should we check if the transaction is mined. - * @param timeoutMs How long (in ms) to poll for transaction mined until aborting. - * @return Transaction receipt with decoded log args. - */ - public async awaitTransactionMinedAsync( - txHash: string, pollingIntervalMs = 1000, timeoutMs?: number): Promise { - let timeoutExceeded = false; - if (timeoutMs) { - setTimeout(() => timeoutExceeded = true, timeoutMs); - } - - const txReceiptPromise = new Promise( - (resolve: (receipt: TransactionReceiptWithDecodedLogs) => void, reject) => { - const intervalId = intervalUtils.setAsyncExcludingInterval(async () => { - if (timeoutExceeded) { - intervalUtils.clearAsyncExcludingInterval(intervalId); - return reject(ZeroExError.TransactionMiningTimeout); - } - - const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash); - if (!_.isNull(transactionReceipt)) { - intervalUtils.clearAsyncExcludingInterval(intervalId); - const logsWithDecodedArgs = _.map( - transactionReceipt.logs, - this._abiDecoder.tryToDecodeLogOrNoop.bind(this._abiDecoder), - ); - const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = { - ...transactionReceipt, - logs: logsWithDecodedArgs, - }; - resolve(transactionReceiptWithDecodedLogArgs); - } - }, pollingIntervalMs); - }); - - return txReceiptPromise; - } - /* - * HACK: `TokenWrapper` needs a token transfer proxy address. `TokenTransferProxy` address is fetched from - * an `ExchangeWrapper`. `ExchangeWrapper` needs `TokenWrapper` to validate orders, creating a dependency cycle. - * In order to break this - we create this function here and pass it as a parameter to the `TokenWrapper` - * and `ProxyWrapper`. - */ - private async _getTokenTransferProxyAddressAsync(): Promise { - const tokenTransferProxyAddress = await (this.exchange as any)._getTokenTransferProxyAddressAsync(); - return tokenTransferProxyAddress; - } -} diff --git a/src/artifacts.ts b/src/artifacts.ts deleted file mode 100644 index 447f9880a..000000000 --- a/src/artifacts.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {Artifact} from './types'; -import * as TokenArtifact from './artifacts/Token.json'; -import * as ExchangeArtifact from './artifacts/Exchange.json'; -import * as EtherTokenArtifact from './artifacts/EtherToken.json'; -import * as TokenRegistryArtifact from './artifacts/TokenRegistry.json'; -import * as TokenTransferProxyArtifact from './artifacts/TokenTransferProxy.json'; - -export const artifacts = { - TokenArtifact: TokenArtifact as any as Artifact, - ExchangeArtifact: ExchangeArtifact as any as Artifact, - EtherTokenArtifact: EtherTokenArtifact as any as Artifact, - TokenRegistryArtifact: TokenRegistryArtifact as any as Artifact, - TokenTransferProxyArtifact: TokenTransferProxyArtifact as any as Artifact, -}; diff --git a/src/artifacts/EtherToken.json b/src/artifacts/EtherToken.json deleted file mode 100644 index 91b23bc94..000000000 --- a/src/artifacts/EtherToken.json +++ /dev/null @@ -1,445 +0,0 @@ -{ - "contract_name": "EtherToken", - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "amount", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "deposit", - "outputs": [], - "payable": true, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "payable": true, - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ], - "unlinked_binary": "0x6060604052341561000c57fe5b5b6107598061001c6000396000f300606060405236156100935763ffffffff60e060020a60003504166306fdde0381146100a4578063095ea7b31461013457806318160ddd1461016757806323b872dd146101895780632e1a7d4d146101c2578063313ce567146101d757806370a08231146101fd57806395d89b411461022b578063a9059cbb146102bb578063d0e30db0146102ee578063dd62ed3e146102f8575b6100a25b61009f61032c565b5b565b005b34156100ac57fe5b6100b461037b565b6040805160208082528351818301528351919283929083019185019080838382156100fa575b8051825260208311156100fa57601f1990920191602091820191016100da565b505050905090810190601f1680156101265780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561013c57fe5b610153600160a060020a03600435166024356103a3565b604080519115158252519081900360200190f35b341561016f57fe5b61017761040e565b60408051918252519081900360200190f35b341561019157fe5b610153600160a060020a0360043581169060243516604435610414565b604080519115158252519081900360200190f35b34156101ca57fe5b6100a2600435610537565b005b34156101df57fe5b6101e76105b8565b6040805160ff9092168252519081900360200190f35b341561020557fe5b610177600160a060020a03600435166105bd565b60408051918252519081900360200190f35b341561023357fe5b6100b46105dc565b6040805160208082528351818301528351919283929083019185019080838382156100fa575b8051825260208311156100fa57601f1990920191602091820191016100da565b505050905090810190601f1680156101265780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156102c357fe5b610153600160a060020a03600435166024356105fd565b604080519115158252519081900360200190f35b6100a261032c565b005b341561030057fe5b610177600160a060020a03600435811690602435166106af565b60408051918252519081900360200190f35b600160a060020a03331660009081526020819052604090205461034f90346106dc565b600160a060020a03331660009081526020819052604090205560025461037590346106dc565b6002555b565b60408051808201909152600b815260a960020a6a22ba3432b9102a37b5b2b702602082015281565b600160a060020a03338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60025481565b600160a060020a03808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906104575750828110155b801561047d5750600160a060020a03841660009081526020819052604090205483810110155b1561052957600160a060020a03808516600090815260208190526040808220805487019055918716815220805484900390556000198110156104e757600160a060020a03808616600090815260016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a031660008051602061070e833981519152856040518082815260200191505060405180910390a36001915061052e565b600091505b5b509392505050565b600160a060020a03331660009081526020819052604090205461055a90826106f6565b600160a060020a03331660009081526020819052604090205560025461058090826106f6565b600255604051600160a060020a0333169082156108fc029083906000818181858888f1935050505015156105b45760006000fd5b5b50565b601281565b600160a060020a0381166000908152602081905260409020545b919050565b604080518082019091526004815260e360020a630ae8aa8902602082015281565b600160a060020a0333166000908152602081905260408120548290108015906106405750600160a060020a03831660009081526020819052604090205482810110155b156106a057600160a060020a03338116600081815260208181526040808320805488900390559387168083529184902080548701905583518681529351919360008051602061070e833981519152929081900390910190a3506001610408565b506000610408565b5b92915050565b600160a060020a038083166000908152600160209081526040808320938516835292905220545b92915050565b6000828201838110156106eb57fe5b8091505b5092915050565b60008282111561070257fe5b508082035b929150505600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820ec42c469bb8ddd5de28c55b9cc393c812397c063a57fb88926e3f6de246318b70029", - "networks": { - "1": { - "links": {}, - "events": { - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - }, - "updated_at": 1502488087000, - "address": "0x2956356cd2a2bf3202f771f50d3d14a367b48070" - }, - "3": { - "links": {}, - "events": { - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - }, - "updated_at": 1506602007000, - "address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a" - }, - "42": { - "links": {}, - "events": { - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - }, - "updated_at": 1502391794392, - "address": "0x05d090b51c40b020eab3bfcb6a2dff130df22e9c" - }, - "50": { - "links": {}, - "events": { - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - }, - "updated_at": 1503318938233, - "address": "0x48bacb9266a570d521063ef5dd96e61686dbe788" - } - }, - "schema_version": "0.0.5", - "updated_at": 1503318938233 -} diff --git a/src/artifacts/Exchange.json b/src/artifacts/Exchange.json deleted file mode 100644 index 734c8f9c7..000000000 --- a/src/artifacts/Exchange.json +++ /dev/null @@ -1,1130 +0,0 @@ -{ - "contract_name": "Exchange", - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "numerator", - "type": "uint256" - }, - { - "name": "denominator", - "type": "uint256" - }, - { - "name": "target", - "type": "uint256" - } - ], - "name": "isRoundingError", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "filled", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "cancelled", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "fillOrdersUpTo", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "cancelTakerTokenAmount", - "type": "uint256" - } - ], - "name": "cancelOrder", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ZRX_TOKEN_CONTRACT", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmounts", - "type": "uint256[]" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "batchFillOrKillOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "fillOrKillOrder", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "getUnavailableTakerTokenAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "signer", - "type": "address" - }, - { - "name": "hash", - "type": "bytes32" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "isValidSignature", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "numerator", - "type": "uint256" - }, - { - "name": "denominator", - "type": "uint256" - }, - { - "name": "target", - "type": "uint256" - } - ], - "name": "getPartialAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "TOKEN_TRANSFER_PROXY_CONTRACT", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmounts", - "type": "uint256[]" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "batchFillOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "cancelTakerTokenAmounts", - "type": "uint256[]" - } - ], - "name": "batchCancelOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "fillOrder", - "outputs": [ - { - "name": "filledTakerTokenAmount", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - } - ], - "name": "getOrderHash", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "EXTERNAL_QUERY_GAS_LIMIT", - "outputs": [ - { - "name": "", - "type": "uint16" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "inputs": [ - { - "name": "_zrxToken", - "type": "address" - }, - { - "name": "_tokenTransferProxy", - "type": "address" - } - ], - "payable": false, - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": false, - "name": "taker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "filledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "filledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidMakerFee", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidTakerFee", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogFill", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "cancelledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "cancelledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogCancel", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "errorId", - "type": "uint8" - }, - { - "indexed": true, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogError", - "type": "event" - } - ], - "unlinked_binary": "0x6060604052341561000c57fe5b604051604080611ed68339810160405280516020909101515b60008054600160a060020a03808516600160a060020a03199283161790925560018054928416929091169190911790555b50505b611e6e806100686000396000f300606060405236156100e05763ffffffff60e060020a60003504166314df96ee81146100e2578063288cdc911461010f5780632ac1262214610134578063363349be14610159578063394c21e71461031b5780633b30ba591461038e5780634f150787146103ba578063741bcc931461059d5780637e9abb50146106135780638163681e1461063857806398024a8b14610677578063add1cbc5146106a2578063b7b2c7d6146106ce578063baa0181d146108b9578063bc61394a146109f4578063cfc4d0ec14610a81578063f06bbf7514610af2578063ffa1ad7414610b19575bfe5b34156100ea57fe5b6100fb600435602435604435610ba9565b604080519115158252519081900360200190f35b341561011757fe5b610122600435610bf7565b60408051918252519081900360200190f35b341561013c57fe5b610122600435610c09565b60408051918252519081900360200190f35b341561016157fe5b61012260048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156101d3576040805160a08181019092529080840287019060059083908390808284375050509183525050600190910190602001610197565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610246576040805160c0818101909252908084028701906006908390839080828437505050918352505060019091019060200161020a565b5050604080516020878301358901803582810280850184019095528084529799893599838101351515999198506060019650929450810192829185019084908082843750506040805187358901803560208181028481018201909552818452989a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989a998901989297509082019550935083925085019084908082843750949650610c1b95505050505050565b60408051918252519081900360200190f35b341561032357fe5b6040805160a08181019092526101229160049160a4918390600590839083908082843750506040805160c08181019092529496958181019594509250600691508390839080828437509395505092359250610d44915050565b60408051918252519081900360200190f35b341561039657fe5b61039e611036565b60408051600160a060020a039092168252519081900360200190f35b34156103c257fe5b61059b60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610434576040805160a081810190925290808402870190600590839083908082843750505091835250506001909101906020016103f8565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156104a7576040805160c0818101909252908084028701906006908390839080828437505050918352505060019091019060200161046b565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843750506040805187358901803560208181028481018201909552818452989a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989a99890198929750908201955093508392508501908490808284375094965061104595505050505050565b005b34156105a557fe5b6040805160a081810190925261059b9160049160a4918390600590839083908082843750506040805160c08181019092529496958181019594509250600691508390839080828437509395505083359360ff6020820135169350604081013592506060013590506110fc565b005b341561061b57fe5b610122600435611121565b60408051918252519081900360200190f35b341561064057fe5b6100fb600160a060020a036004351660243560ff6044351660643560843561114d565b604080519115158252519081900360200190f35b341561067f57fe5b610122600435602435604435611205565b60408051918252519081900360200190f35b34156106aa57fe5b61039e611224565b60408051600160a060020a039092168252519081900360200190f35b34156106d657fe5b61059b60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610748576040805160a0818101909252908084028701906005908390839080828437505050918352505060019091019060200161070c565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156107bb576040805160c0818101909252908084028701906006908390839080828437505050918352505060019091019060200161077f565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284375050604080516020808901358a01803580830284810184018652818552999b8b3515159b909a950198509296508101945090925082919085019084908082843750506040805187358901803560208181028481018201909552818452989a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989a99890198929750908201955093508392508501908490808284375094965061123395505050505050565b005b34156108c157fe5b61059b60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610933576040805160a081810190925290808402870190600590839083908082843750505091835250506001909101906020016108f7565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156109a6576040805160c0818101909252908084028701906006908390839080828437505050918352505060019091019060200161096a565b505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437509496506112ed95505050505050565b005b34156109fc57fe5b6040805160a08181019092526101229160049160a4918390600590839083908082843750506040805160c08181019092529496958181019594509250600691508390839080828437509395505083359360208101351515935060ff6040820135169250606081013591506080013561135a565b60408051918252519081900360200190f35b3415610a8957fe5b6040805160a08181019092526101229160049160a4918390600590839083908082843750506040805160c0818101909252949695818101959450925060069150839083908082843750939550611838945050505050565b60408051918252519081900360200190f35b3415610afa57fe5b610b0261192b565b6040805161ffff9092168252519081900360200190f35b3415610b2157fe5b610b29611931565b604080516020808252835181830152835191928392908301918501908083838215610b6f575b805182526020831115610b6f57601f199092019160209182019101610b4f565b505050905090810190601f168015610b9b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060006000848685099150811515610bc55760009250610bee565b610be4610bd583620f4240611953565b610bdf8887611953565b611982565b90506103e8811192505b50509392505050565b60026020526000908152604090205481565b60036020526000908152604090205481565b600080805b8951811015610d3357896000815181101515610c3857fe5b6020908102909101015160035b6020020151600160a060020a03168a82815181101515610c6157fe5b6020908102909101015160035b6020020151600160a060020a031614610c875760006000fd5b610d1b82610d168c84815181101515610c9c57fe5b906020019060200201518c85815181101515610cb457fe5b90602001906020020151610cc88d8861199f565b8c8c88815181101515610cd757fe5b906020019060200201518c89815181101515610cef57fe5b906020019060200201518c8a815181101515610d0757fe5b9060200190602002015161135a565b6119b6565b915087821415610d2a57610d33565b5b600101610c20565b8192505b5050979650505050505050565b6000610d4e611dc6565b60408051610160810190915260009081908088835b60209081029190910151600160a060020a03168252018860015b60209081029190910151600160a060020a03168252018860025b60209081029190910151600160a060020a03168252018860035b60209081029190910151600160a060020a03168252018860045b60209081029190910151600160a060020a03168252018760005b602090810291909101518252018760015b602090810291909101518252018760025b602090810291909101518252018760035b602090810291909101518252018760045b60200201518152602001610e3d8989611838565b9052805190935033600160a060020a03908116911614610e5d5760006000fd5b60008360a00151118015610e75575060008360c00151115b8015610e815750600085115b1515610e8d5760006000fd5b6101208301514210610ec95761014083015160005b60405160ff9190911690600080516020611e2383398151915290600090a36000935061102c565b610ee48360c00151610edf856101400151611121565b61199f565b9150610ef085836119d0565b9050801515610f2d576101408301516001610ea2565b60405160ff9190911690600080516020611e2383398151915290600090a36000935061102c565b610140830151600090815260036020526040902054610f4c90826119b6565b610140840151600090815260036020526040908190209190915580840180516060860180518451606060020a600160a060020a03948516810282529184169091026014820152935193849003602801909320608087015187519351945160c089015160a08a0151939692851695909416937f67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b0458713193610fea918991611205565b6101408a015160408051600160a060020a0395861681529390941660208401528284019190915260608201889052608082015290519081900360a00190a48093505b5050509392505050565b600054600160a060020a031681565b60005b86518110156110f2576110e9878281518110151561106257fe5b90602001906020020151878381518110151561107a57fe5b90602001906020020151878481518110151561109257fe5b9060200190602002015187858151811015156110aa57fe5b9060200190602002015187868151811015156110c257fe5b9060200190602002015187878151811015156110da57fe5b906020019060200201516110fc565b5b600101611048565b5b50505050505050565b8361110d878787600088888861135a565b146111185760006000fd5b5b505050505050565b600081815260026020908152604080832054600390925282205461114591906119b6565b90505b919050565b604080517f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c8101869052815190819003603c018120600082815260208381018552928401819052835191825260ff8716828401528184018690526060820185905292516001926080808401939192601f1981019281900390910190868661646e5a03f115156111dc57fe5b505060206040510351600160a060020a031686600160a060020a03161490505b95945050505050565b600061121a6112148584611953565b84611982565b90505b9392505050565b600154600160a060020a031681565b60005b87518110156112e2576112d8888281518110151561125057fe5b90602001906020020151888381518110151561126857fe5b90602001906020020151888481518110151561128057fe5b9060200190602002015188888681518110151561129957fe5b9060200190602002015188878151811015156112b157fe5b906020019060200201518888815181101515610d0757fe5b9060200190602002015161135a565b505b600101611236565b5b5050505050505050565b60005b835181101561135357611349848281518110151561130a57fe5b90602001906020020151848381518110151561132257fe5b90602001906020020151848481518110151561133a57fe5b90602001906020020151610d44565b505b6001016112f0565b5b50505050565b6000611364611dc6565b6000600060006000610160604051908101604052808e600060058110151561138857fe5b60209081029190910151600160a060020a03168252018e60015b60209081029190910151600160a060020a03168252018e60025b60209081029190910151600160a060020a03168252018e60035b60209081029190910151600160a060020a03168252018e60045b60209081029190910151600160a060020a03168252018d60005b602090810291909101518252018d60015b602090810291909101518252018d60025b602090810291909101518252018d60035b602090810291909101518252018d60045b602002015181526020016114628f8f611838565b90526020810151909550600160a060020a03161580611496575033600160a060020a03168560200151600160a060020a0316145b15156114a25760006000fd5b60008560a001511180156114ba575060008560c00151115b80156114c6575060008b115b15156114d25760006000fd5b6114e885600001518661014001518b8b8b61114d565b15156114f45760006000fd5b61012085015142106115305761014085015160005b60405160ff9190911690600080516020611e2383398151915290600090a360009550611828565b61154b8560c00151610edf876101400151611121565b61199f565b93506115578b856119d0565b9550851515611594576101408501516001611509565b60405160ff9190911690600080516020611e2383398151915290600090a360009550611828565b6115a7868660c001518760a00151610ba9565b156115e0576101408501516002611509565b60405160ff9190911690600080516020611e2383398151915290600090a360009550611828565b891580156115f557506115f385876119ea565b155b1561162e576101408501516003611509565b60405160ff9190911690600080516020611e2383398151915290600090a360009550611828565b611641868660c001518760a00151611205565b61014086015160009081526002602052604090205490935061166390876119b6565b6101408601516000908152600260205260409081902091909155850151855161168e91903386611c46565b151561169a5760006000fd5b6116ae856060015133876000015189611c46565b15156116ba5760006000fd5b6080850151600160a060020a03161561176e5760008560e00151111561171c576116ed868660c001518760e00151611205565b6000548651608088015192945061171092600160a060020a039092169185611c46565b151561171c5760006000fd5b5b6000856101000151111561176e5761173f868660c00151876101000151611205565b600054608087015191925061176291600160a060020a0390911690339084611c46565b151561176e5760006000fd5b5b5b60408086018051606080890180518551606060020a600160a060020a0395861681028252918516909102601482015285519081900360280181206080808d01518d51975194516101408f0151338916865295881660208601528716848a01529483018b905282018d905260a0820189905260c0820188905260e08201929092529451909491831693909216917f0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb3918190036101000190a45b5050505050979650505050505050565b60003083825b60200201518460015b60200201518560025b60200201518660035b60200201518760045b60200201518760005b60200201518860015b60200201518960025b60200201518a60035b60200201518b60045b60200201518c60055b602002015160408051606060020a600160a060020a039e8f16810282529c8e168d0260148201529a8d168c0260288c0152988c168b02603c8b0152968b168a0260508a01529490991690970260648701526078860191909152609885015260b884019490945260d883019490945260f8820192909252610118810192909252519081900361013801902090505b92915050565b61138781565b604080518082019091526005815260dc60020a640312e302e302602082015281565b600082820283158061196f575082848281151561196c57fe5b04145b151561197757fe5b8091505b5092915050565b60006000828481151561199157fe5b0490508091505b5092915050565b6000828211156119ab57fe5b508082035b92915050565b60008282018381101561197757fe5b8091505b5092915050565b60008183106119df57816119e1565b825b90505b92915050565b600060006000600060006000600060006000339750611a128a8c60c001518d60a00151611205565b60808c0151909750600160a060020a031615611bc75760005460408c015160608d015160c08e015160e08f0151600160a060020a0394851693851684149a50939091169091149650611a66918c9190611205565b9350611a7c8a8c60c001518d6101000151611205565b925085611a895783611a93565b611a9387856119b6565b5b915084611aa15782611aab565b611aab8a846119b6565b5b6000548c519192508391611ac991600160a060020a031690611cd5565b1080611aee57506000548b518391611aec91600160a060020a0390911690611d50565b105b80611b0e57506000548190611b0c90600160a060020a03168a611cd5565b105b80611b2e57506000548190611b2c90600160a060020a03168a611d50565b105b15611b3c5760009850611c38565b85158015611b74575086611b588c604001518d60000151611cd5565b1080611b74575086611b728c604001518d60000151611d50565b105b5b15611b835760009850611c38565b84158015611bb3575089611b9b8c606001518a611cd5565b1080611bb3575089611bb18c606001518a611d50565b105b5b15611bc25760009850611c38565b611c32565b86611bda8c604001518d60000151611cd5565b1080611bf6575086611bf48c604001518d60000151611d50565b105b80611c0d575089611c0b8c606001518a611cd5565b105b80611c24575089611c228c606001518a611d50565b105b15611c325760009850611c38565b5b600198505b505050505050505092915050565b6001546040805160006020918201819052825160e160020a630aed65f5028152600160a060020a03898116600483015288811660248301528781166044830152606482018790529351919493909316926315dacbea92608480830193919282900301818787803b1515611cb557fe5b6102c65a03f11515611cc357fe5b5050604051519150505b949350505050565b600082600160a060020a03166370a0823161138761ffff16846040518363ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600088803b1515611d3557fe5b87f11515611d3f57fe5b505060405151925050505b92915050565b6001546040805160e160020a636eb1769f028152600160a060020a0384811660048301529283166024820152905160009285169163dd62ed3e916113879160448082019260209290919082900301818888803b1515611d3557fe5b87f11515611d3f57fe5b505060405151925050505b92915050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915290560036d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e90a165627a7a72305820ee5481a0a94774cee2beaad49e754979e4db70aed7ee4a00103d60def15aa8da0029", - "networks": { - "1": { - "links": {}, - "events": { - "0x0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb3": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": false, - "name": "taker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "filledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "filledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidMakerFee", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidTakerFee", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogFill", - "type": "event" - }, - "0x67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b04587131": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "cancelledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "cancelledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogCancel", - "type": "event" - }, - "0x36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e90": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "errorId", - "type": "uint8" - }, - { - "indexed": true, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogError", - "type": "event" - } - }, - "updated_at": 1502480340000, - "address": "0x12459c951127e0c374ff9105dda097662a027093" - }, - "3": { - "links": {}, - "events": { - "0x0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb3": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": false, - "name": "taker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "filledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "filledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidMakerFee", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidTakerFee", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogFill", - "type": "event" - }, - "0x67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b04587131": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "cancelledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "cancelledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogCancel", - "type": "event" - }, - "0x36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e90": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "errorId", - "type": "uint8" - }, - { - "indexed": true, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogError", - "type": "event" - } - }, - "updated_at": 1506602007000, - "address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac" - }, - "42": { - "links": {}, - "events": { - "0x0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb3": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": false, - "name": "taker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "filledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "filledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidMakerFee", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidTakerFee", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogFill", - "type": "event" - }, - "0x67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b04587131": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "cancelledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "cancelledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogCancel", - "type": "event" - }, - "0x36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e90": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "errorId", - "type": "uint8" - }, - { - "indexed": true, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogError", - "type": "event" - } - }, - "updated_at": 1502391794390, - "address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364" - }, - "50": { - "links": {}, - "events": { - "0x0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb3": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": false, - "name": "taker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "filledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "filledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidMakerFee", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidTakerFee", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogFill", - "type": "event" - }, - "0x67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b04587131": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "cancelledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "cancelledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogCancel", - "type": "event" - }, - "0x36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e90": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "errorId", - "type": "uint8" - }, - { - "indexed": true, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogError", - "type": "event" - } - }, - "updated_at": 1503318938231, - "address": "0xb69e673309512a9d726f87304c6984054f87a93b" - } - }, - "schema_version": "0.0.5", - "updated_at": 1503318938231 -} diff --git a/src/artifacts/Token.json b/src/artifacts/Token.json deleted file mode 100644 index e922ff66d..000000000 --- a/src/artifacts/Token.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "contract_name": "Token", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "success", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "supply", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "success", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "balance", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "success", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "remaining", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ], - "unlinked_binary": "0x6060604052341561000c57fe5b5b6101e08061001c6000396000f3006060604052361561005c5763ffffffff60e060020a600035041663095ea7b3811461005e57806318160ddd1461009157806323b872dd146100b357806370a08231146100ec578063a9059cbb1461005e578063dd62ed3e1461014d575bfe5b341561006657fe5b61007d600160a060020a0360043516602435610181565b604080519115158252519081900360200190f35b341561009957fe5b6100a161018a565b60408051918252519081900360200190f35b34156100bb57fe5b61007d600160a060020a0360043581169060243516604435610190565b604080519115158252519081900360200190f35b34156100f457fe5b6100a1600160a060020a036004351661019a565b60408051918252519081900360200190f35b341561006657fe5b61007d600160a060020a0360043516602435610181565b604080519115158252519081900360200190f35b341561015557fe5b6100a1600160a060020a0360043581169060243516610181565b60408051918252519081900360200190f35b60005b92915050565b60005b90565b60005b9392505050565b60005b919050565b60005b92915050565b60005b929150505600a165627a7a723058202e3f7ac17048343c0d0ea24fccb64620577374eeeed61539e543df4025d7d0db0029", - "networks": {}, - "schema_version": "0.0.5", - "updated_at": 1503317882695 -} \ No newline at end of file diff --git a/src/artifacts/TokenRegistry.json b/src/artifacts/TokenRegistry.json deleted file mode 100644 index 5a0564a69..000000000 --- a/src/artifacts/TokenRegistry.json +++ /dev/null @@ -1,1211 +0,0 @@ -{ - "contract_name": "TokenRegistry", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_index", - "type": "uint256" - } - ], - "name": "removeToken", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_name", - "type": "string" - } - ], - "name": "getTokenAddressByName", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_symbol", - "type": "string" - } - ], - "name": "getTokenAddressBySymbol", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_swarmHash", - "type": "bytes" - } - ], - "name": "setTokenSwarmHash", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_token", - "type": "address" - } - ], - "name": "getTokenMetaData", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_name", - "type": "string" - }, - { - "name": "_symbol", - "type": "string" - }, - { - "name": "_decimals", - "type": "uint8" - }, - { - "name": "_ipfsHash", - "type": "bytes" - }, - { - "name": "_swarmHash", - "type": "bytes" - } - ], - "name": "addToken", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_name", - "type": "string" - } - ], - "name": "setTokenName", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "tokens", - "outputs": [ - { - "name": "token", - "type": "address" - }, - { - "name": "name", - "type": "string" - }, - { - "name": "symbol", - "type": "string" - }, - { - "name": "decimals", - "type": "uint8" - }, - { - "name": "ipfsHash", - "type": "bytes" - }, - { - "name": "swarmHash", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "tokenAddresses", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_name", - "type": "string" - } - ], - "name": "getTokenByName", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getTokenAddresses", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_ipfsHash", - "type": "bytes" - } - ], - "name": "setTokenIpfsHash", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_symbol", - "type": "string" - } - ], - "name": "getTokenBySymbol", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_symbol", - "type": "string" - } - ], - "name": "setTokenSymbol", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogAddToken", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogRemoveToken", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldName", - "type": "string" - }, - { - "indexed": false, - "name": "newName", - "type": "string" - } - ], - "name": "LogTokenNameChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSymbol", - "type": "string" - }, - { - "indexed": false, - "name": "newSymbol", - "type": "string" - } - ], - "name": "LogTokenSymbolChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldIpfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newIpfsHash", - "type": "bytes" - } - ], - "name": "LogTokenIpfsHashChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSwarmHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newSwarmHash", - "type": "bytes" - } - ], - "name": "LogTokenSwarmHashChange", - "type": "event" - } - ], - "unlinked_binary": "0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b612cc5806100316000396000f300606060405236156100ca5763ffffffff60e060020a60003504166313baf1e681146100cc5780632fbfeba9146100ed5780633550b6d91461015f57806356318820146101d15780637abccac9146102335780638da5cb5b1461044d578063a880319d14610479578063c370c86d1461059a578063e4860339146105fc578063e5df8b841461082b578063e73fc0c31461085a578063ee8c24b814610aae578063eef05f6514610b19578063efa74f1f14610b7b578063f036417f14610dcf578063f2fde38b14610e31575bfe5b34156100d457fe5b6100eb600160a060020a0360043516602435610e4f565b005b34156100f557fe5b610143600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965061134895505050505050565b60408051600160a060020a039092168252519081900360200190f35b341561016757fe5b610143600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496506113bb95505050505050565b60408051600160a060020a039092168252519081900360200190f35b34156101d957fe5b60408051602060046024803582810135601f81018590048502860185019096528585526100eb958335600160a060020a0316959394604494939290920191819084018382808284375094965061142e95505050505050565b005b341561023b57fe5b61024f600160a060020a03600435166115cf565b6040518087600160a060020a0316600160a060020a0316815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a8181518152602001915080519060200190808383600083146102ca575b8051825260208311156102ca57601f1990920191602091820191016102aa565b505050905090810190601f1680156102f65780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b01908083838215610335575b80518252602083111561033557601f199092019160209182019101610315565b505050905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50858103835287518152875160209182019189019080838382156103a0575b8051825260208311156103a057601f199092019160209182019101610380565b505050905090810190601f1680156103cc5780820380516001836020036101000a031916815260200191505b508581038252865181528651602091820191880190808383821561040b575b80518252602083111561040b57601f1990920191602091820191016103eb565b505050905090810190601f1680156104375780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b341561045557fe5b6101436118ba565b60408051600160a060020a039092168252519081900360200190f35b341561048157fe5b60408051602060046024803582810135601f81018590048502860185019096528585526100eb958335600160a060020a0316959394604494939290920191819084018382808284375050604080516020601f89358b0180359182018390048302840183019094528083529799988101979196509182019450925082915084018382808284375050604080516020601f818a01358b0180359182018390048302840183018552818452989a60ff8b35169a90999401975091955091820193509150819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506118c995505050505050565b005b34156105a257fe5b60408051602060046024803582810135601f81018590048502860185019096528585526100eb958335600160a060020a03169593946044949392909201918190840183828082843750949650611e7a95505050505050565b005b341561060457fe5b610618600160a060020a03600435166121a1565b60408051600160a060020a038816815260ff8516606082015260c0602082018181528854600260001961010060018416150201909116049183018290529192830190608084019060a085019060e08601908b9080156106b85780601f1061068d576101008083540402835291602001916106b8565b820191906000526020600020905b81548152906001019060200180831161069b57829003601f168201915b505085810384528954600260001961010060018416150201909116048082526020909101908a90801561072c5780601f106107015761010080835404028352916020019161072c565b820191906000526020600020905b81548152906001019060200180831161070f57829003601f168201915b50508581038352875460026000196101006001841615020190911604808252602090910190889080156107a05780601f10610775576101008083540402835291602001916107a0565b820191906000526020600020905b81548152906001019060200180831161078357829003601f168201915b50508581038252865460026000196101006001841615020190911604808252602090910190879080156108145780601f106107e957610100808354040283529160200191610814565b820191906000526020600020905b8154815290600101906020018083116107f757829003601f168201915b50509a505050505050505050505060405180910390f35b341561083357fe5b6101436004356121dc565b60408051600160a060020a039092168252519081900360200190f35b341561086257fe5b61024f600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965061220e95505050505050565b6040518087600160a060020a0316600160a060020a0316815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a8181518152602001915080519060200190808383600083146102ca575b8051825260208311156102ca57601f1990920191602091820191016102aa565b505050905090810190601f1680156102f65780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b01908083838215610335575b80518252602083111561033557601f199092019160209182019101610315565b505050905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50858103835287518152875160209182019189019080838382156103a0575b8051825260208311156103a057601f199092019160209182019101610380565b505050905090810190601f1680156103cc5780820380516001836020036101000a031916815260200191505b508581038252865181528651602091820191880190808383821561040b575b80518252602083111561040b57601f1990920191602091820191016103eb565b505050905090810190601f1680156104375780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b3415610ab657fe5b610abe6122c1565b6040805160208082528351818301528351919283929083019185810191028083838215610b06575b805182526020831115610b0657601f199092019160209182019101610ae6565b5050509050019250505060405180910390f35b3415610b2157fe5b60408051602060046024803582810135601f81018590048502860185019096528585526100eb958335600160a060020a0316959394604494939290920191819084018382808284375094965061232a95505050505050565b005b3415610b8357fe5b61024f600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496506124cb95505050505050565b6040518087600160a060020a0316600160a060020a0316815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a8181518152602001915080519060200190808383600083146102ca575b8051825260208311156102ca57601f1990920191602091820191016102aa565b505050905090810190601f1680156102f65780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b01908083838215610335575b80518252602083111561033557601f199092019160209182019101610315565b505050905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50858103835287518152875160209182019189019080838382156103a0575b8051825260208311156103a057601f199092019160209182019101610380565b505050905090810190601f1680156103cc5780820380516001836020036101000a031916815260200191505b508581038252865181528651602091820191880190808383821561040b575b80518252602083111561040b57601f1990920191602091820191016103eb565b505050905090810190601f1680156104375780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b3415610dd757fe5b60408051602060046024803582810135601f81018590048502860185019096528585526100eb958335600160a060020a0316959394604494939290920191819084018382808284375094965061257e95505050505050565b005b3415610e3957fe5b6100eb600160a060020a03600435166128a4565b005b6000805433600160a060020a03908116911614610e6c5760006000fd5b600160a060020a038084166000908152600160205260409020548491161515610e955760006000fd5b83600160a060020a0316600484815481101515610eae57fe5b906000526020600020900160005b9054600160a060020a036101009290920a90041614610edb5760006000fd5b600480546000198101908110610eed57fe5b906000526020600020900160005b9054906101000a9004600160a060020a0316600484815481101515610f1c57fe5b906000526020600020900160005b6101000a815481600160a060020a030219169083600160a060020a031602179055506001600481818054905003915081610f6491906128f0565b50600160a060020a0380851660009081526001602081815260409283902080546003820154855160ff90911695810186905260a0808252838601805460026000199882161561010002989098011687900491830182905293995091909616957f32c54f1e2ea75844ded7517e7dbcd3895da7cd0c28f9ab9f9cf6ecf5f83762c695929489019360048a019260058b0192918291908201906060830190608084019060c08501908b9080156110595780601f1061102e57610100808354040283529160200191611059565b820191906000526020600020905b81548152906001019060200180831161103c57829003601f168201915b505085810384528954600260001961010060018416150201909116048082526020909101908a9080156110cd5780601f106110a2576101008083540402835291602001916110cd565b820191906000526020600020905b8154815290600101906020018083116110b057829003601f168201915b50508581038352875460026000196101006001841615020190911604808252602090910190889080156111415780601f1061111657610100808354040283529160200191611141565b820191906000526020600020905b81548152906001019060200180831161112457829003601f168201915b50508581038252865460026000196101006001841615020190911604808252602090910190879080156111b55780601f1061118a576101008083540402835291602001916111b5565b820191906000526020600020905b81548152906001019060200180831161119857829003601f168201915b5050995050505050505050505060405180910390a2600282600201604051808280546001816001161561010002031660029004801561122b5780601f1061120957610100808354040283529182019161122b565b820191906000526020600020905b815481529060010190602001808311611217575b5050915050908152602001604051809103902060006101000a815490600160a060020a03021916905560038260010160405180828054600181600116156101000203166002900480156112b55780601f106112935761010080835404028352918201916112b5565b820191906000526020600020905b8154815290600101906020018083116112a1575b5050928352505060408051602092819003830190208054600160a060020a0319908116909155600160a060020a038716600090815260019384905291822080549091168155916113079083018261291a565b61131560028301600061291a565b60038201805460ff1916905561132f60048301600061291a565b61133d60058301600061291a565b50505b5b505b505050565b60006003826040518082805190602001908083835b6020831061137c5780518252601f19909201916020918201910161135d565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054600160a060020a0316925050505b919050565b60006002826040518082805190602001908083835b6020831061137c5780518252601f19909201916020918201910161135d565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054600160a060020a0316925050505b919050565b6000805433600160a060020a0390811691161461144b5760006000fd5b600160a060020a0380841660009081526001602052604090205484911615156114745760006000fd5b600160a060020a0384166000818152600160208181526040928390208351848152600582018054600295811615610100026000190116949094049481018590529096507fc3168fdc13112e44a031057dbf6c609b33353addb4d8037d24543e22cbfe2acd9388928291908201906060830190869080156115355780601f1061150a57610100808354040283529160200191611535565b820191906000526020600020905b81548152906001019060200180831161151857829003601f168201915b505083810382528451815284516020918201918601908083838215611575575b80518252602083111561157557601f199092019160209182019101611555565b505050905090810190601f1680156115a15780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a282516115c590600584019060208601906129aa565b505b5b505b505050565b60006115d9612a29565b6115e1612a29565b60006115eb612a29565b6115f3612a29565b6115fb612a4d565b600160a060020a03888116600090815260016020818152604092839020835160c0810185528154909516855280830180548551600261010096831615969096026000190190911694909404601f8101849004840285018401909552848452909385830193928301828280156116b15780601f10611686576101008083540402835291602001916116b1565b820191906000526020600020905b81548152906001019060200180831161169457829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f810183900483028501830190915280845293810193908301828280156117435780601f1061171857610100808354040283529160200191611743565b820191906000526020600020905b81548152906001019060200180831161172657829003601f168201915b5050509183525050600382015460ff1660208083019190915260048301805460408051601f600260001960018616156101000201909416939093049283018590048502810185018252828152940193928301828280156117e45780601f106117b9576101008083540402835291602001916117e4565b820191906000526020600020905b8154815290600101906020018083116117c757829003601f168201915b505050918352505060058201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156118785780601f1061184d57610100808354040283529160200191611878565b820191906000526020600020905b81548152906001019060200180831161185b57829003601f168201915b5050509190925250508151602083015160408401516060850151608086015160a0870151949d50929b50909950975095509350909150505b5091939550919395565b600054600160a060020a031681565b60005433600160a060020a039081169116146118e55760006000fd5b600160a060020a038087166000908152600160205260409020548791161561190d5760006000fd5b86600160a060020a03811615156119245760006000fd5b856000600160a060020a03166002826040518082805190602001908083835b602083106119625780518252601f199092019160209182019101611943565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054600160a060020a03169290921491506119a990505760006000fd5b876000600160a060020a03166003826040518082805190602001908083835b602083106119e75780518252601f1990920191602091820191016119c8565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054600160a060020a0316929092149150611a2e90505760006000fd5b6040805160c081018252600160a060020a038c811680835260208084018e81528486018e905260ff8d166060860152608085018c905260a085018b9052600092835260018083529590922084518154600160a060020a03191694169390931783559051805193949293611aa89385019291909101906129aa565b5060408201518051611ac49160028401916020909101906129aa565b50606082015160038201805460ff191660ff90921691909117905560808201518051611afa9160048401916020909101906129aa565b5060a08201518051611b169160058401916020909101906129aa565b50506004805490915060018101611b2d83826128f0565b916000526020600020900160005b8c909190916101000a815481600160a060020a030219169083600160a060020a0316021790555050896002896040518082805190602001908083835b60208310611b965780518252601f199092019160209182019101611b77565b51815160209384036101000a600019018019909216911617905292019485525060405193849003810184208054600160a060020a031916600160a060020a03969096169590951790945550508a518c926003928d9290918291908401908083835b60208310611c165780518252601f199092019160209182019101611bf7565b51815160209384036101000a60001901801990921691161790529201948552506040805194859003820185208054600160a060020a031916600160a060020a0397881617905560ff8d169085015260a08085528e51908501528d51948f16947fd8d928b0b50ca11d9dc273236b46f3526515b03602f71f3a6af4f45bd9fa9144948f94508e93508d928d928d92918291828201916060840191608085019160c0860191908c01908083838215611ce7575b805182526020831115611ce757601f199092019160209182019101611cc7565b505050905090810190601f168015611d135780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b01908083838215611d52575b805182526020831115611d5257601f199092019160209182019101611d32565b505050905090810190601f168015611d7e5780820380516001836020036101000a031916815260200191505b5085810383528751815287516020918201918901908083838215611dbd575b805182526020831115611dbd57601f199092019160209182019101611d9d565b505050905090810190601f168015611de95780820380516001836020036101000a031916815260200191505b5085810382528651815286516020918201918801908083838215611e28575b805182526020831115611e2857601f199092019160209182019101611e08565b505050905090810190601f168015611e545780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390a25b5b505b505b505b505b505050505050565b6000805433600160a060020a03908116911614611e975760006000fd5b600160a060020a038084166000908152600160205260409020548491161515611ec05760006000fd5b826000600160a060020a03166003826040518082805190602001908083835b60208310611efe5780518252601f199092019160209182019101611edf565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054600160a060020a0316929092149150611f4590505760006000fd5b600160a060020a03851660008181526001602081815260409283902083518481528184018054600295811615610100026000190116949094049481018590529097507f4a6dbfc867b179991dec22ff19960f0a94d8d9d891fc556f547764670340e8ae9389928291908201906060830190869080156120055780601f10611fda57610100808354040283529160200191612005565b820191906000526020600020905b815481529060010190602001808311611fe857829003601f168201915b505083810382528451815284516020918201918601908083838215612045575b80518252602083111561204557601f199092019160209182019101612025565b505050905090810190601f1680156120715780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a260038360010160405180828054600181600116156101000203166002900480156120e15780601f106120bf5761010080835404028352918201916120e1565b820191906000526020600020905b8154815290600101906020018083116120cd575b5050928352505060405190819003602090810182208054600160a060020a031916905585518792600392889282918401908083835b602083106121355780518252601f199092019160209182019101612116565b51815160209384036101000a60001901801990921691161790529201948552506040519384900381019093208054600160a060020a031916600160a060020a03959095169490941790935550855161133d925060018601918701906129aa565b505b5b505b505b505050565b600160208190526000918252604090912080546003820154600160a060020a0390911692820191600281019160ff1690600481019060050186565b60048054829081106121ea57fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b6000612218612a29565b612220612a29565b600061222a612a29565b612232612a29565b60006003886040518082805190602001908083835b602083106122665780518252601f199092019160209182019101612247565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054600160a060020a031692506122aa91508290506115cf565b9650965096509650965096505b5091939550919395565b6122c9612a29565b600480548060200260200160405190810160405280929190818152602001828054801561231f57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311612301575b505050505090505b90565b6000805433600160a060020a039081169116146123475760006000fd5b600160a060020a0380841660009081526001602052604090205484911615156123705760006000fd5b600160a060020a0384166000818152600160208181526040928390208351848152600482018054600295811615610100026000190116949094049481018590529096507f5b19f79ac4e8cfa820815502e11615f1a449e28155dc289ec5cac1a11f9086949388928291908201906060830190869080156124315780601f1061240657610100808354040283529160200191612431565b820191906000526020600020905b81548152906001019060200180831161241457829003601f168201915b505083810382528451815284516020918201918601908083838215612471575b80518252602083111561247157601f199092019160209182019101612451565b505050905090810190601f16801561249d5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a282516115c590600484019060208601906129aa565b505b5b505b505050565b60006124d5612a29565b6124dd612a29565b60006124e7612a29565b6124ef612a29565b60006002886040518082805190602001908083835b602083106122665780518252601f199092019160209182019101612247565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054600160a060020a031692506122aa91508290506115cf565b9650965096509650965096505b5091939550919395565b6000805433600160a060020a0390811691161461259b5760006000fd5b600160a060020a0380841660009081526001602052604090205484911615156125c45760006000fd5b826000600160a060020a03166002826040518082805190602001908083835b602083106126025780518252601f1990920191602091820191016125e3565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922054600160a060020a031692909214915061264990505760006000fd5b600160a060020a038516600081815260016020818152604092839020835184815260028083018054958616156101000260001901909516049481018590529097507f53d878a6530e56c9bc96548fa0a8cae4f1d1f49c86b0e934c086b992ebb6998f9389928291908201906060830190869080156127085780601f106126dd57610100808354040283529160200191612708565b820191906000526020600020905b8154815290600101906020018083116126eb57829003601f168201915b505083810382528451815284516020918201918601908083838215612748575b80518252602083111561274857601f199092019160209182019101612728565b505050905090810190601f1680156127745780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a260028360020160405180828054600181600116156101000203166002900480156127e45780601f106127c25761010080835404028352918201916127e4565b820191906000526020600020905b8154815290600101906020018083116127d0575b5050928352505060405190819003602090810182208054600160a060020a031916905585518792600292889282918401908083835b602083106128385780518252601f199092019160209182019101612819565b51815160209384036101000a60001901801990921691161790529201948552506040519384900381019093208054600160a060020a031916600160a060020a03959095169490941790935550855161133d925060028601918701906129aa565b505b5b505b505b505050565b60005433600160a060020a039081169116146128c05760006000fd5b600160a060020a038116156128eb5760008054600160a060020a031916600160a060020a0383161790555b5b5b50565b81548183558181151161134357600083815260209020611343918101908301612c54565b5b505050565b50805460018160011615610100020316600290046000825580601f1061294057506128eb565b601f0160209004906000526020600020908101906128eb9190612c54565b5b50565b50805460018160011615610100020316600290046000825580601f1061294057506128eb565b601f0160209004906000526020600020908101906128eb9190612c54565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106129eb57805160ff1916838001178555612a18565b82800160010185558215612a18579182015b82811115612a185782518255916020019190600101906129fd565b5b50612a25929150612c54565b5090565b60408051602081019091526000815290565b60408051602081019091526000815290565b6040805160c081019091526000815260208101612a68612a29565b8152602001612a75612a29565b815260006020820152604001612a89612a29565b8152602001612a96612a29565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106129eb57805160ff1916838001178555612a18565b82800160010185558215612a18579182015b82811115612a185782518255916020019190600101906129fd565b5b50612a25929150612c54565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106129eb57805160ff1916838001178555612a18565b82800160010185558215612a18579182015b82811115612a185782518255916020019190600101906129fd565b5b50612a25929150612c54565b5090565b81548183558181151161134357600083815260209020611343918101908301612c54565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106129eb57805160ff1916838001178555612a18565b82800160010185558215612a18579182015b82811115612a185782518255916020019190600101906129fd565b5b50612a25929150612c54565b5090565b60408051602081019091526000815290565b61232791905b80821115612a255760008155600101612c5a565b5090565b90565b60408051602081019091526000815290565b604080516020810190915260008152905600a165627a7a72305820f2f49870071c0109a35c5649b17fcc2e8194d1f11d27fa5772c57ddacf6975090029", - "networks": { - "1": { - "links": {}, - "events": { - "0xd8d928b0b50ca11d9dc273236b46f3526515b03602f71f3a6af4f45bd9fa9144": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogAddToken", - "type": "event" - }, - "0x32c54f1e2ea75844ded7517e7dbcd3895da7cd0c28f9ab9f9cf6ecf5f83762c6": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogRemoveToken", - "type": "event" - }, - "0x4a6dbfc867b179991dec22ff19960f0a94d8d9d891fc556f547764670340e8ae": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldName", - "type": "string" - }, - { - "indexed": false, - "name": "newName", - "type": "string" - } - ], - "name": "LogTokenNameChange", - "type": "event" - }, - "0x53d878a6530e56c9bc96548fa0a8cae4f1d1f49c86b0e934c086b992ebb6998f": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSymbol", - "type": "string" - }, - { - "indexed": false, - "name": "newSymbol", - "type": "string" - } - ], - "name": "LogTokenSymbolChange", - "type": "event" - }, - "0x5b19f79ac4e8cfa820815502e11615f1a449e28155dc289ec5cac1a11f908694": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldIpfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newIpfsHash", - "type": "bytes" - } - ], - "name": "LogTokenIpfsHashChange", - "type": "event" - }, - "0xc3168fdc13112e44a031057dbf6c609b33353addb4d8037d24543e22cbfe2acd": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSwarmHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newSwarmHash", - "type": "bytes" - } - ], - "name": "LogTokenSwarmHashChange", - "type": "event" - } - }, - "updated_at": 1502488442000, - "address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c" - }, - "3": { - "links": {}, - "events": { - "0xd8d928b0b50ca11d9dc273236b46f3526515b03602f71f3a6af4f45bd9fa9144": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogAddToken", - "type": "event" - }, - "0x32c54f1e2ea75844ded7517e7dbcd3895da7cd0c28f9ab9f9cf6ecf5f83762c6": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogRemoveToken", - "type": "event" - }, - "0x4a6dbfc867b179991dec22ff19960f0a94d8d9d891fc556f547764670340e8ae": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldName", - "type": "string" - }, - { - "indexed": false, - "name": "newName", - "type": "string" - } - ], - "name": "LogTokenNameChange", - "type": "event" - }, - "0x53d878a6530e56c9bc96548fa0a8cae4f1d1f49c86b0e934c086b992ebb6998f": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSymbol", - "type": "string" - }, - { - "indexed": false, - "name": "newSymbol", - "type": "string" - } - ], - "name": "LogTokenSymbolChange", - "type": "event" - }, - "0x5b19f79ac4e8cfa820815502e11615f1a449e28155dc289ec5cac1a11f908694": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldIpfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newIpfsHash", - "type": "bytes" - } - ], - "name": "LogTokenIpfsHashChange", - "type": "event" - }, - "0xc3168fdc13112e44a031057dbf6c609b33353addb4d8037d24543e22cbfe2acd": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSwarmHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newSwarmHash", - "type": "bytes" - } - ], - "name": "LogTokenSwarmHashChange", - "type": "event" - } - }, - "updated_at": 1506602007000, - "address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed" - }, - "42": { - "links": {}, - "events": { - "0xd8d928b0b50ca11d9dc273236b46f3526515b03602f71f3a6af4f45bd9fa9144": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogAddToken", - "type": "event" - }, - "0x32c54f1e2ea75844ded7517e7dbcd3895da7cd0c28f9ab9f9cf6ecf5f83762c6": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogRemoveToken", - "type": "event" - }, - "0x4a6dbfc867b179991dec22ff19960f0a94d8d9d891fc556f547764670340e8ae": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldName", - "type": "string" - }, - { - "indexed": false, - "name": "newName", - "type": "string" - } - ], - "name": "LogTokenNameChange", - "type": "event" - }, - "0x53d878a6530e56c9bc96548fa0a8cae4f1d1f49c86b0e934c086b992ebb6998f": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSymbol", - "type": "string" - }, - { - "indexed": false, - "name": "newSymbol", - "type": "string" - } - ], - "name": "LogTokenSymbolChange", - "type": "event" - }, - "0x5b19f79ac4e8cfa820815502e11615f1a449e28155dc289ec5cac1a11f908694": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldIpfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newIpfsHash", - "type": "bytes" - } - ], - "name": "LogTokenIpfsHashChange", - "type": "event" - }, - "0xc3168fdc13112e44a031057dbf6c609b33353addb4d8037d24543e22cbfe2acd": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSwarmHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newSwarmHash", - "type": "bytes" - } - ], - "name": "LogTokenSwarmHashChange", - "type": "event" - } - }, - "updated_at": 1502391794385, - "address": "0xf18e504561f4347bea557f3d4558f559dddbae7f" - }, - "50": { - "links": {}, - "events": { - "0xd8d928b0b50ca11d9dc273236b46f3526515b03602f71f3a6af4f45bd9fa9144": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogAddToken", - "type": "event" - }, - "0x32c54f1e2ea75844ded7517e7dbcd3895da7cd0c28f9ab9f9cf6ecf5f83762c6": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogRemoveToken", - "type": "event" - }, - "0x4a6dbfc867b179991dec22ff19960f0a94d8d9d891fc556f547764670340e8ae": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldName", - "type": "string" - }, - { - "indexed": false, - "name": "newName", - "type": "string" - } - ], - "name": "LogTokenNameChange", - "type": "event" - }, - "0x53d878a6530e56c9bc96548fa0a8cae4f1d1f49c86b0e934c086b992ebb6998f": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSymbol", - "type": "string" - }, - { - "indexed": false, - "name": "newSymbol", - "type": "string" - } - ], - "name": "LogTokenSymbolChange", - "type": "event" - }, - "0x5b19f79ac4e8cfa820815502e11615f1a449e28155dc289ec5cac1a11f908694": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldIpfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newIpfsHash", - "type": "bytes" - } - ], - "name": "LogTokenIpfsHashChange", - "type": "event" - }, - "0xc3168fdc13112e44a031057dbf6c609b33353addb4d8037d24543e22cbfe2acd": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSwarmHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newSwarmHash", - "type": "bytes" - } - ], - "name": "LogTokenSwarmHashChange", - "type": "event" - } - }, - "updated_at": 1503318938228, - "address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082" - } - }, - "schema_version": "0.0.5", - "updated_at": 1503318938228 -} diff --git a/src/artifacts/TokenTransferProxy.json b/src/artifacts/TokenTransferProxy.json deleted file mode 100644 index beeb16cfe..000000000 --- a/src/artifacts/TokenTransferProxy.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "contract_name": "TokenTransferProxy", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "token", - "type": "address" - }, - { - "name": "from", - "type": "address" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "target", - "type": "address" - } - ], - "name": "addAuthorizedAddress", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "authorities", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "target", - "type": "address" - } - ], - "name": "removeAuthorizedAddress", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "authorized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getAuthorizedAddresses", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "target", - "type": "address" - }, - { - "indexed": true, - "name": "caller", - "type": "address" - } - ], - "name": "LogAuthorizedAddressAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "target", - "type": "address" - }, - { - "indexed": true, - "name": "caller", - "type": "address" - } - ], - "name": "LogAuthorizedAddressRemoved", - "type": "event" - } - ], - "unlinked_binary": "0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b6106e6806100316000396000f300606060405236156100725763ffffffff60e060020a60003504166315dacbea811461007457806342f1181e146100b3578063494503d4146100d157806370712939146101005780638da5cb5b1461011e578063b91816111461014a578063d39de6e91461017a578063f2fde38b146101e5575bfe5b341561007c57fe5b61009f600160a060020a0360043581169060243581169060443516606435610203565b604080519115158252519081900360200190f35b34156100bb57fe5b6100cf600160a060020a03600435166102ae565b005b34156100d957fe5b6100e4600435610390565b60408051600160a060020a039092168252519081900360200190f35b341561010857fe5b6100cf600160a060020a03600435166103c2565b005b341561012657fe5b6100e461055a565b60408051600160a060020a039092168252519081900360200190f35b341561015257fe5b61009f600160a060020a0360043516610569565b604080519115158252519081900360200190f35b341561018257fe5b61018a61057e565b60408051602080825283518183015283519192839290830191858101910280838382156101d2575b8051825260208311156101d257601f1990920191602091820191016101b2565b5050509050019250505060405180910390f35b34156101ed57fe5b6100cf600160a060020a03600435166105e7565b005b600160a060020a03331660009081526001602052604081205460ff16151561022b5760006000fd5b6040805160006020918201819052825160e060020a6323b872dd028152600160a060020a0388811660048301528781166024830152604482018790529351938916936323b872dd9360648084019491938390030190829087803b151561028d57fe5b6102c65a03f1151561029b57fe5b5050604051519150505b5b949350505050565b60005433600160a060020a039081169116146102ca5760006000fd5b600160a060020a038116600090815260016020526040902054819060ff16156102f35760006000fd5b600160a060020a0382166000908152600160208190526040909120805460ff191682179055600280549091810161032a8382610633565b916000526020600020900160005b81546101009190910a600160a060020a0381810219909216868316918202179092556040513390911692507f94bb87f4c15c4587ff559a7584006fa01ddf9299359be6b512b94527aa961aca90600090a35b5b505b50565b600280548290811061039e57fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b6000805433600160a060020a039081169116146103df5760006000fd5b600160a060020a038216600090815260016020526040902054829060ff1615156104095760006000fd5b600160a060020a0383166000908152600160205260408120805460ff1916905591505b6002548210156105195782600160a060020a031660028381548110151561044f57fe5b906000526020600020900160005b9054906101000a9004600160a060020a0316600160a060020a0316141561050d5760028054600019810190811061049057fe5b906000526020600020900160005b9054906101000a9004600160a060020a03166002838154811015156104bf57fe5b906000526020600020900160005b6101000a815481600160a060020a030219169083600160a060020a0316021790555060016002818180549050039150816105079190610633565b50610519565b5b60019091019061042c565b604051600160a060020a0333811691908516907ff5b347a1e40749dd050f5f07fbdbeb7e3efa9756903044dd29401fd1d4bb4a1c90600090a35b5b505b5050565b600054600160a060020a031681565b60016020526000908152604090205460ff1681565b610586610687565b60028054806020026020016040519081016040528092919081815260200182805480156105dc57602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116105be575b505050505090505b90565b60005433600160a060020a039081169116146106035760006000fd5b600160a060020a0381161561038d5760008054600160a060020a031916600160a060020a0383161790555b5b5b50565b81548183558181151161055357600083815260209020610553918101908301610699565b5b505050565b81548183558181151161055357600083815260209020610553918101908301610699565b5b505050565b60408051602081019091526000815290565b6105e491905b808211156106b3576000815560010161069f565b5090565b905600a165627a7a72305820d2924957bb88a128789172e164d874fe5445218fc2dde2f5eb265839a1f341a20029", - "networks": {}, - "schema_version": "0.0.5", - "updated_at": 1503318938227 -} diff --git a/src/bignumber_config.ts b/src/bignumber_config.ts deleted file mode 100644 index 2d5214e6f..000000000 --- a/src/bignumber_config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import BigNumber from 'bignumber.js'; - -export const bigNumberConfigs = { - configure() { - // By default BigNumber's `toString` method converts to exponential notation if the value has - // more then 20 digits. We want to avoid this behavior, so we set EXPONENTIAL_AT to a high number - BigNumber.config({ - EXPONENTIAL_AT: 1000, - }); - }, -}; diff --git a/src/contract.ts b/src/contract.ts deleted file mode 100644 index 1aacc65dc..000000000 --- a/src/contract.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as Web3 from 'web3'; -import * as _ from 'lodash'; -import promisify = require('es6-promisify'); -import {SchemaValidator, schemas} from '0x-json-schemas'; -import {AbiType} from './types'; - -export class Contract implements Web3.ContractInstance { - public address: string; - public abi: Web3.ContractAbi; - private contract: Web3.ContractInstance; - private defaults: Partial; - private validator: SchemaValidator; - // This class instance is going to be populated with functions and events depending on the ABI - // and we don't know their types in advance - [name: string]: any; - constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial) { - this.contract = web3ContractInstance; - this.address = web3ContractInstance.address; - this.abi = web3ContractInstance.abi; - this.defaults = defaults; - this.populateEvents(); - this.populateFunctions(); - this.validator = new SchemaValidator(); - } - private populateFunctions(): void { - const functionsAbi = _.filter(this.abi, abiPart => abiPart.type === AbiType.Function); - _.forEach(functionsAbi, (functionAbi: Web3.MethodAbi) => { - if (functionAbi.constant) { - const cbStyleCallFunction = this.contract[functionAbi.name].call; - this[functionAbi.name] = { - callAsync: promisify(cbStyleCallFunction, this.contract), - }; - } else { - const cbStyleFunction = this.contract[functionAbi.name]; - const cbStyleEstimateGasFunction = this.contract[functionAbi.name].estimateGas; - this[functionAbi.name] = { - estimateGasAsync: promisify(cbStyleEstimateGasFunction, this.contract), - sendTransactionAsync: this.promisifyWithDefaultParams(cbStyleFunction), - }; - } - }); - } - private populateEvents(): void { - const eventsAbi = _.filter(this.abi, abiPart => abiPart.type === AbiType.Event); - _.forEach(eventsAbi, (eventAbi: Web3.EventAbi) => { - this[eventAbi.name] = this.contract[eventAbi.name]; - }); - } - private promisifyWithDefaultParams(fn: (...args: any[]) => void): (...args: any[]) => Promise { - const promisifiedWithDefaultParams = (...args: any[]) => { - const promise = new Promise((resolve, reject) => { - const lastArg = args[args.length - 1]; - let txData: Partial = {}; - if (this.isTxData(lastArg)) { - txData = args.pop(); - } - txData = { - ...this.defaults, - ...txData, - }; - const callback = (err: Error, data: any) => { - if (_.isNull(err)) { - resolve(data); - } else { - reject(err); - } - }; - args.push(txData); - args.push(callback); - fn.apply(this.contract, args); - }); - return promise; - }; - return promisifiedWithDefaultParams; - } - private isTxData(lastArg: any): boolean { - const isValid = this.validator.isValid(lastArg, schemas.txDataSchema); - return isValid; - } -} diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts deleted file mode 100644 index 7997b1647..000000000 --- a/src/contract_wrappers/contract_wrapper.ts +++ /dev/null @@ -1,152 +0,0 @@ -import * as _ from 'lodash'; -import * as Web3 from 'web3'; -import {BlockAndLogStreamer, Block} from 'ethereumjs-blockstream'; -import {Web3Wrapper} from '../web3_wrapper'; -import {AbiDecoder} from '../utils/abi_decoder'; -import { - ZeroExError, - InternalZeroExError, - Artifact, - LogWithDecodedArgs, - RawLog, - ContractEvents, - SubscriptionOpts, - IndexedFilterValues, - EventCallback, - BlockParamLiteral, - ContractEventArgs, -} from '../types'; -import {constants} from '../utils/constants'; -import {intervalUtils} from '../utils/interval_utils'; -import {filterUtils} from '../utils/filter_utils'; - -export class ContractWrapper { - protected _web3Wrapper: Web3Wrapper; - private _abiDecoder?: AbiDecoder; - private _blockAndLogStreamer: BlockAndLogStreamer|undefined; - private _blockAndLogStreamInterval: NodeJS.Timer; - private _filters: {[filterToken: string]: Web3.FilterObject}; - private _filterCallbacks: {[filterToken: string]: EventCallback}; - private _onLogAddedSubscriptionToken: string|undefined; - private _onLogRemovedSubscriptionToken: string|undefined; - constructor(web3Wrapper: Web3Wrapper, abiDecoder?: AbiDecoder) { - this._web3Wrapper = web3Wrapper; - this._abiDecoder = abiDecoder; - this._filters = {}; - this._filterCallbacks = {}; - this._blockAndLogStreamer = undefined; - this._onLogAddedSubscriptionToken = undefined; - this._onLogRemovedSubscriptionToken = undefined; - } - /** - * Cancels all existing subscriptions - */ - public unsubscribeAll(): void { - const filterTokens = _.keys(this._filterCallbacks); - _.each(filterTokens, filterToken => { - this._unsubscribe(filterToken); - }); - } - protected _unsubscribe(filterToken: string, err?: Error): void { - if (_.isUndefined(this._filters[filterToken])) { - throw new Error(ZeroExError.SubscriptionNotFound); - } - if (!_.isUndefined(err)) { - const callback = this._filterCallbacks[filterToken]; - callback(err, undefined); - } - delete this._filters[filterToken]; - delete this._filterCallbacks[filterToken]; - if (_.isEmpty(this._filters)) { - this._stopBlockAndLogStream(); - } - } - protected _subscribe( - address: string, eventName: ContractEvents, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi, - callback: EventCallback): string { - const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi); - if (_.isUndefined(this._blockAndLogStreamer)) { - this._startBlockAndLogStream(); - } - const filterToken = filterUtils.generateUUID(); - this._filters[filterToken] = filter; - this._filterCallbacks[filterToken] = callback; - return filterToken; - } - protected async _getLogsAsync( - address: string, eventName: ContractEvents, subscriptionOpts: SubscriptionOpts, - indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise>> { - const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, subscriptionOpts); - const logs = await this._web3Wrapper.getLogsAsync(filter); - const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this)); - return logsWithDecodedArguments; - } - protected _tryToDecodeLogOrNoop( - log: Web3.LogEntry): LogWithDecodedArgs|RawLog { - if (_.isUndefined(this._abiDecoder)) { - throw new Error(InternalZeroExError.NoAbiDecoder); - } - const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoop(log); - return logWithDecodedArgs; - } - protected async _instantiateContractIfExistsAsync( - artifact: Artifact, addressIfExists?: string): Promise { - const contractInstance = - await this._web3Wrapper.getContractInstanceFromArtifactAsync(artifact, addressIfExists); - return contractInstance; - } - private _onLogStateChanged(removed: boolean, log: Web3.LogEntry): void { - _.forEach(this._filters, (filter: Web3.FilterObject, filterToken: string) => { - if (filterUtils.matchesFilter(log, filter)) { - const decodedLog = this._tryToDecodeLogOrNoop(log) as LogWithDecodedArgs; - const logEvent = { - ...decodedLog, - removed, - }; - this._filterCallbacks[filterToken](null, logEvent); - } - }); - } - private _startBlockAndLogStream(): void { - this._blockAndLogStreamer = new BlockAndLogStreamer( - this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper), - this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), - ); - const catchAllLogFilter = {}; - this._blockAndLogStreamer.addLogFilter(catchAllLogFilter); - this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval( - this._reconcileBlockAsync.bind(this), constants.DEFAULT_BLOCK_POLLING_INTERVAL, - ); - let removed = false; - this._onLogAddedSubscriptionToken = this._blockAndLogStreamer.subscribeToOnLogAdded( - this._onLogStateChanged.bind(this, removed), - ); - removed = true; - this._onLogRemovedSubscriptionToken = this._blockAndLogStreamer.subscribeToOnLogRemoved( - this._onLogStateChanged.bind(this, removed), - ); - } - private _stopBlockAndLogStream(): void { - (this._blockAndLogStreamer as BlockAndLogStreamer).unsubscribeFromOnLogAdded( - this._onLogAddedSubscriptionToken as string); - (this._blockAndLogStreamer as BlockAndLogStreamer).unsubscribeFromOnLogRemoved( - this._onLogRemovedSubscriptionToken as string); - intervalUtils.clearAsyncExcludingInterval(this._blockAndLogStreamInterval); - delete this._blockAndLogStreamer; - } - private async _reconcileBlockAsync(): Promise { - try { - const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest); - // We need to coerce to Block type cause Web3.Block includes types for mempool blocks - if (!_.isUndefined(this._blockAndLogStreamer)) { - // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined - this._blockAndLogStreamer.reconcileNewBlock(latestBlock as any as Block); - } - } catch (err) { - const filterTokens = _.keys(this._filterCallbacks); - _.each(filterTokens, filterToken => { - this._unsubscribe(filterToken, err); - }); - } - } -} diff --git a/src/contract_wrappers/ether_token_wrapper.ts b/src/contract_wrappers/ether_token_wrapper.ts deleted file mode 100644 index 3cd2f0224..000000000 --- a/src/contract_wrappers/ether_token_wrapper.ts +++ /dev/null @@ -1,87 +0,0 @@ -import * as _ from 'lodash'; -import BigNumber from 'bignumber.js'; -import {Web3Wrapper} from '../web3_wrapper'; -import {ContractWrapper} from './contract_wrapper'; -import {TokenWrapper} from './token_wrapper'; -import {EtherTokenContract, ZeroExError} from '../types'; -import {assert} from '../utils/assert'; -import {artifacts} from '../artifacts'; - -/** - * This class includes all the functionality related to interacting with a wrapped Ether ERC20 token contract. - * The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back. - */ -export class EtherTokenWrapper extends ContractWrapper { - private _etherTokenContractIfExists?: EtherTokenContract; - private _tokenWrapper: TokenWrapper; - private _contractAddressIfExists?: string; - constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper, contractAddressIfExists?: string) { - super(web3Wrapper); - this._tokenWrapper = tokenWrapper; - this._contractAddressIfExists = contractAddressIfExists; - } - /** - * Deposit ETH into the Wrapped ETH smart contract and issues the equivalent number of wrapped ETH tokens - * to the depositor address. These wrapped ETH tokens can be used in 0x trades and are redeemable for 1-to-1 - * for ETH. - * @param amountInWei Amount of ETH in Wei the caller wishes to deposit. - * @param depositor The hex encoded user Ethereum address that would like to make the deposit. - * @return Transaction hash. - */ - public async depositAsync(amountInWei: BigNumber, depositor: string): Promise { - assert.isValidBaseUnitAmount('amountInWei', amountInWei); - await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper); - - const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(depositor); - assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit); - - const wethContract = await this._getEtherTokenContractAsync(); - const txHash = await wethContract.deposit.sendTransactionAsync({ - from: depositor, - value: amountInWei, - }); - return txHash; - } - /** - * Withdraw ETH to the withdrawer's address from the wrapped ETH smart contract in exchange for the - * equivalent number of wrapped ETH tokens. - * @param amountInWei Amount of ETH in Wei the caller wishes to withdraw. - * @param withdrawer The hex encoded user Ethereum address that would like to make the withdrawl. - * @return Transaction hash. - */ - public async withdrawAsync(amountInWei: BigNumber, withdrawer: string): Promise { - assert.isValidBaseUnitAmount('amountInWei', amountInWei); - await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper); - - const wethContractAddress = await this.getContractAddressAsync(); - const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(wethContractAddress, withdrawer); - assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal); - - const wethContract = await this._getEtherTokenContractAsync(); - const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, { - from: withdrawer, - }); - return txHash; - } - /** - * Retrieves the Wrapped Ether token contract address - * @return The Wrapped Ether token contract address - */ - public async getContractAddressAsync(): Promise { - const wethContract = await this._getEtherTokenContractAsync(); - return wethContract.address; - } - private _invalidateContractInstance(): void { - delete this._etherTokenContractIfExists; - } - private async _getEtherTokenContractAsync(): Promise { - if (!_.isUndefined(this._etherTokenContractIfExists)) { - return this._etherTokenContractIfExists; - } - const contractInstance = await this._instantiateContractIfExistsAsync( - artifacts.EtherTokenArtifact, this._contractAddressIfExists, - ); - this._etherTokenContractIfExists = contractInstance as EtherTokenContract; - return this._etherTokenContractIfExists; - } -} diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts deleted file mode 100644 index fe0c5bc00..000000000 --- a/src/contract_wrappers/exchange_wrapper.ts +++ /dev/null @@ -1,866 +0,0 @@ -import * as _ from 'lodash'; -import * as Web3 from 'web3'; -import BigNumber from 'bignumber.js'; -import {schemas} from '0x-json-schemas'; -import {Web3Wrapper} from '../web3_wrapper'; -import { - ECSignature, - ExchangeContract, - ExchangeContractErrCodes, - ExchangeContractErrs, - ZeroExError, - OrderValues, - OrderAddresses, - Order, - SignedOrder, - ExchangeEvents, - SubscriptionOpts, - IndexedFilterValues, - OrderCancellationRequest, - OrderFillRequest, - LogErrorContractEventArgs, - LogFillContractEventArgs, - LogCancelContractEventArgs, - LogWithDecodedArgs, - MethodOpts, - ValidateOrderFillableOpts, - OrderTransactionOpts, - RawLog, - EventCallback, - ExchangeContractEventArgs, - DecodedLogArgs, -} from '../types'; -import {assert} from '../utils/assert'; -import {utils} from '../utils/utils'; -import {OrderValidationUtils} from '../utils/order_validation_utils'; -import {ContractWrapper} from './contract_wrapper'; -import {TokenWrapper} from './token_wrapper'; -import {decorators} from '../utils/decorators'; -import {AbiDecoder} from '../utils/abi_decoder'; -import {ExchangeTransferSimulator} from '../utils/exchange_transfer_simulator'; -import {artifacts} from '../artifacts'; - -const SHOULD_VALIDATE_BY_DEFAULT = true; - -/** - * This class includes all the functionality related to calling methods and subscribing to - * events of the 0x Exchange smart contract. - */ -export class ExchangeWrapper extends ContractWrapper { - private _exchangeContractIfExists?: ExchangeContract; - private _orderValidationUtils: OrderValidationUtils; - private _tokenWrapper: TokenWrapper; - private _exchangeContractErrCodesToMsg = { - [ExchangeContractErrCodes.ERROR_FILL_EXPIRED]: ExchangeContractErrs.OrderFillExpired, - [ExchangeContractErrCodes.ERROR_CANCEL_EXPIRED]: ExchangeContractErrs.OrderFillExpired, - [ExchangeContractErrCodes.ERROR_FILL_NO_VALUE]: ExchangeContractErrs.OrderRemainingFillAmountZero, - [ExchangeContractErrCodes.ERROR_CANCEL_NO_VALUE]: ExchangeContractErrs.OrderRemainingFillAmountZero, - [ExchangeContractErrCodes.ERROR_FILL_TRUNCATION]: ExchangeContractErrs.OrderFillRoundingError, - [ExchangeContractErrCodes.ERROR_FILL_BALANCE_ALLOWANCE]: ExchangeContractErrs.FillBalanceAllowanceError, - }; - private _contractAddressIfExists?: string; - private static _getOrderAddressesAndValues(order: Order): [OrderAddresses, OrderValues] { - const orderAddresses: OrderAddresses = [ - order.maker, - order.taker, - order.makerTokenAddress, - order.takerTokenAddress, - order.feeRecipient, - ]; - const orderValues: OrderValues = [ - order.makerTokenAmount, - order.takerTokenAmount, - order.makerFee, - order.takerFee, - order.expirationUnixTimestampSec, - order.salt, - ]; - return [orderAddresses, orderValues]; - } - constructor(web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, - tokenWrapper: TokenWrapper, contractAddressIfExists?: string) { - super(web3Wrapper, abiDecoder); - this._tokenWrapper = tokenWrapper; - this._orderValidationUtils = new OrderValidationUtils(tokenWrapper, this); - this._contractAddressIfExists = contractAddressIfExists; - } - /** - * Returns the unavailable takerAmount of an order. Unavailable amount is defined as the total - * amount that has been filled or cancelled. The remaining takerAmount can be calculated by - * subtracting the unavailable amount from the total order takerAmount. - * @param orderHash The hex encoded orderHash for which you would like to retrieve the - * unavailable takerAmount. - * @param methodOpts Optional arguments this method accepts. - * @return The amount of the order (in taker tokens) that has either been filled or canceled. - */ - public async getUnavailableTakerAmountAsync(orderHash: string, - methodOpts?: MethodOpts): Promise { - assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); - - const exchangeContract = await this._getExchangeContractAsync(); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync( - orderHash, defaultBlock, - ); - // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber - unavailableTakerTokenAmount = new BigNumber(unavailableTakerTokenAmount); - return unavailableTakerTokenAmount; - } - /** - * Retrieve the takerAmount of an order that has already been filled. - * @param orderHash The hex encoded orderHash for which you would like to retrieve the filled takerAmount. - * @param methodOpts Optional arguments this method accepts. - * @return The amount of the order (in taker tokens) that has already been filled. - */ - public async getFilledTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise { - assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); - - const exchangeContract = await this._getExchangeContractAsync(); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let fillAmountInBaseUnits = await exchangeContract.filled.callAsync(orderHash, defaultBlock); - // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber - fillAmountInBaseUnits = new BigNumber(fillAmountInBaseUnits); - return fillAmountInBaseUnits; - } - /** - * Retrieve the takerAmount of an order that has been cancelled. - * @param orderHash The hex encoded orderHash for which you would like to retrieve the - * cancelled takerAmount. - * @param methodOpts Optional arguments this method accepts. - * @return The amount of the order (in taker tokens) that has been cancelled. - */ - public async getCanceledTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise { - assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); - - const exchangeContract = await this._getExchangeContractAsync(); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let cancelledAmountInBaseUnits = await exchangeContract.cancelled.callAsync(orderHash, defaultBlock); - // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber - cancelledAmountInBaseUnits = new BigNumber(cancelledAmountInBaseUnits); - return cancelledAmountInBaseUnits; - } - /** - * Fills a signed order with an amount denominated in baseUnits of the taker token. - * Since the order in which transactions are included in the next block is indeterminate, race-conditions - * could arise where a users balance or allowance changes before the fillOrder executes. Because of this, - * we allow you to specify `shouldThrowOnInsufficientBalanceOrAllowance`. - * If false, the smart contract will not throw if the parties - * do not have sufficient balances/allowances, preserving gas costs. Setting it to true forgoes this check - * and causes the smart contract to throw (using all the gas supplied) instead. - * @param signedOrder An object that conforms to the SignedOrder interface. - * @param fillTakerTokenAmount The amount of the order (in taker tokens baseUnits) that - * you wish to fill. - * @param shouldThrowOnInsufficientBalanceOrAllowance Whether or not you wish for the contract call to throw - * if upon execution the tokens cannot be transferred. - * @param takerAddress The user Ethereum address who would like to fill this order. - * Must be available via the supplied Web3.Provider - * passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.contractCallErrorHandler - public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber, - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - takerAddress: string, - orderTransactionOpts?: OrderTransactionOpts): Promise { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const exchangeInstance = await this._getExchangeContractAsync(); - const shouldValidate = _.isUndefined(orderTransactionOpts) ? - SHOULD_VALIDATE_BY_DEFAULT : - orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); - await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); - } - - const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder); - - const gas = await exchangeInstance.fillOrder.estimateGasAsync( - orderAddresses, - orderValues, - fillTakerTokenAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, - { - from: takerAddress, - }, - ); - const txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync( - orderAddresses, - orderValues, - fillTakerTokenAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, - { - from: takerAddress, - gas, - }, - ); - return txHash; - } - /** - * Sequentially and atomically fills signedOrders up to the specified takerTokenFillAmount. - * If the fill amount is reached - it succeeds and does not fill the rest of the orders. - * If fill amount is not reached - it fills as much of the fill amount as possible and succeeds. - * @param signedOrders The array of signedOrders that you would like to fill until - * takerTokenFillAmount is reached. - * @param fillTakerTokenAmount The total amount of the takerTokens you would like to fill. - * @param shouldThrowOnInsufficientBalanceOrAllowance Whether or not you wish for the contract call to throw if - * upon execution any of the tokens cannot be transferred. - * If set to false, the call will continue to fill subsequent - * signedOrders even when some cannot be filled. - * @param takerAddress The user Ethereum address who would like to fill these - * orders. Must be available via the supplied Web3.Provider - * passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.contractCallErrorHandler - public async fillOrdersUpToAsync(signedOrders: SignedOrder[], fillTakerTokenAmount: BigNumber, - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - takerAddress: string, - orderTransactionOpts?: OrderTransactionOpts): Promise { - assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); - const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress); - assert.hasAtMostOneUniqueValue(takerTokenAddresses, - ExchangeContractErrs.MultipleTakerTokensInFillUpToDisallowed); - const exchangeContractAddresses = _.map(signedOrders, signedOrder => signedOrder.exchangeContractAddress); - assert.hasAtMostOneUniqueValue(exchangeContractAddresses, - ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const shouldValidate = _.isUndefined(orderTransactionOpts) ? - SHOULD_VALIDATE_BY_DEFAULT : - orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); - for (const signedOrder of signedOrders) { - await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); - } - } - - if (_.isEmpty(signedOrders)) { - throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - } - - const orderAddressesValuesAndSignatureArray = _.map(signedOrders, signedOrder => { - return [ - ...ExchangeWrapper._getOrderAddressesAndValues(signedOrder), - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, - ]; - }); - // We use _.unzip because _.unzip doesn't type check if values have different types :'( - const [orderAddressesArray, orderValuesArray, vArray, rArray, sArray] = _.unzip( - orderAddressesValuesAndSignatureArray, - ); - - const exchangeInstance = await this._getExchangeContractAsync(); - const gas = await exchangeInstance.fillOrdersUpTo.estimateGasAsync( - orderAddressesArray, - orderValuesArray, - fillTakerTokenAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - vArray, - rArray, - sArray, - { - from: takerAddress, - }, - ); - const txHash = await exchangeInstance.fillOrdersUpTo.sendTransactionAsync( - orderAddressesArray, - orderValuesArray, - fillTakerTokenAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - vArray, - rArray, - sArray, - { - from: takerAddress, - gas, - }, - ); - return txHash; - } - /** - * Batch version of fillOrderAsync. - * Executes multiple fills atomically in a single transaction. - * If shouldThrowOnInsufficientBalanceOrAllowance is set to false, it will continue filling subsequent orders even - * when earlier ones fail. - * When shouldThrowOnInsufficientBalanceOrAllowance is set to true, if any fill fails, the entire batch fails. - * @param orderFillRequests An array of objects that conform to the - * OrderFillRequest interface. - * @param shouldThrowOnInsufficientBalanceOrAllowance Whether or not you wish for the contract call to throw - * if upon execution any of the tokens cannot be - * transferred. If set to false, the call will continue to - * fill subsequent signedOrders even when some - * cannot be filled. - * @param takerAddress The user Ethereum address who would like to fill - * these orders. Must be available via the supplied - * Web3.Provider passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.contractCallErrorHandler - public async batchFillOrdersAsync(orderFillRequests: OrderFillRequest[], - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - takerAddress: string, - orderTransactionOpts?: OrderTransactionOpts): Promise { - assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema); - const exchangeContractAddresses = _.map( - orderFillRequests, - orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress, - ); - assert.hasAtMostOneUniqueValue(exchangeContractAddresses, - ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress); - assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - const shouldValidate = _.isUndefined(orderTransactionOpts) ? - SHOULD_VALIDATE_BY_DEFAULT : - orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); - for (const orderFillRequest of orderFillRequests) { - await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, - takerAddress, zrxTokenAddress, - ); - } - } - if (_.isEmpty(orderFillRequests)) { - throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - } - - const orderAddressesValuesAmountsAndSignatureArray = _.map(orderFillRequests, orderFillRequest => { - return [ - ...ExchangeWrapper._getOrderAddressesAndValues(orderFillRequest.signedOrder), - orderFillRequest.takerTokenFillAmount, - orderFillRequest.signedOrder.ecSignature.v, - orderFillRequest.signedOrder.ecSignature.r, - orderFillRequest.signedOrder.ecSignature.s, - ]; - }); - // We use _.unzip because _.unzip doesn't type check if values have different types :'( - const [orderAddressesArray, orderValuesArray, fillTakerTokenAmounts, vArray, rArray, sArray] = _.unzip( - orderAddressesValuesAmountsAndSignatureArray, - ); - - const exchangeInstance = await this._getExchangeContractAsync(); - const gas = await exchangeInstance.batchFillOrders.estimateGasAsync( - orderAddressesArray, - orderValuesArray, - fillTakerTokenAmounts, - shouldThrowOnInsufficientBalanceOrAllowance, - vArray, - rArray, - sArray, - { - from: takerAddress, - }, - ); - const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync( - orderAddressesArray, - orderValuesArray, - fillTakerTokenAmounts, - shouldThrowOnInsufficientBalanceOrAllowance, - vArray, - rArray, - sArray, - { - from: takerAddress, - gas, - }, - ); - return txHash; - } - /** - * Attempts to fill a specific amount of an order. If the entire amount specified cannot be filled, - * the fill order is abandoned. - * @param signedOrder An object that conforms to the SignedOrder interface. The - * signedOrder you wish to fill. - * @param fillTakerTokenAmount The total amount of the takerTokens you would like to fill. - * @param takerAddress The user Ethereum address who would like to fill this order. - * Must be available via the supplied Web3.Provider passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.contractCallErrorHandler - public async fillOrKillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber, - takerAddress: string, - orderTransactionOpts?: OrderTransactionOpts): Promise { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - - const exchangeInstance = await this._getExchangeContractAsync(); - - const shouldValidate = _.isUndefined(orderTransactionOpts) ? - SHOULD_VALIDATE_BY_DEFAULT : - orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); - await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); - } - - const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder); - - const gas = await exchangeInstance.fillOrKillOrder.estimateGasAsync( - orderAddresses, - orderValues, - fillTakerTokenAmount, - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, - { - from: takerAddress, - }, - ); - const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync( - orderAddresses, - orderValues, - fillTakerTokenAmount, - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, - { - from: takerAddress, - gas, - }, - ); - return txHash; - } - /** - * Batch version of fillOrKill. Allows a taker to specify a batch of orders that will either be atomically - * filled (each to the specified fillAmount) or aborted. - * @param orderFillRequests An array of objects that conform to the OrderFillRequest interface. - * @param takerAddress The user Ethereum address who would like to fill there orders. - * Must be available via the supplied Web3.Provider passed to 0x.js. - * @param orderTransactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.contractCallErrorHandler - public async batchFillOrKillAsync(orderFillRequests: OrderFillRequest[], - takerAddress: string, - orderTransactionOpts?: OrderTransactionOpts): Promise { - assert.doesConformToSchema('orderFillRequests', orderFillRequests, - schemas.orderFillRequestsSchema); - const exchangeContractAddresses = _.map( - orderFillRequests, - orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress, - ); - assert.hasAtMostOneUniqueValue(exchangeContractAddresses, - ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - if (_.isEmpty(orderFillRequests)) { - throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - } - const exchangeInstance = await this._getExchangeContractAsync(); - - const shouldValidate = _.isUndefined(orderTransactionOpts) ? - SHOULD_VALIDATE_BY_DEFAULT : - orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); - for (const orderFillRequest of orderFillRequests) { - await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, - takerAddress, zrxTokenAddress, - ); - } - } - - const orderAddressesValuesAndTakerTokenFillAmounts = _.map(orderFillRequests, request => { - return [ - ...ExchangeWrapper._getOrderAddressesAndValues(request.signedOrder), - request.takerTokenFillAmount, - request.signedOrder.ecSignature.v, - request.signedOrder.ecSignature.r, - request.signedOrder.ecSignature.s, - ]; - }); - - // We use _.unzip because _.unzip doesn't type check if values have different types :'( - const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] = - _.unzip(orderAddressesValuesAndTakerTokenFillAmounts); - - const gas = await exchangeInstance.batchFillOrKillOrders.estimateGasAsync( - orderAddresses, - orderValues, - fillTakerTokenAmounts, - vParams, - rParams, - sParams, - { - from: takerAddress, - }, - ); - const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync( - orderAddresses, - orderValues, - fillTakerTokenAmounts, - vParams, - rParams, - sParams, - { - from: takerAddress, - gas, - }, - ); - return txHash; - } - /** - * Cancel a given fill amount of an order. Cancellations are cumulative. - * @param order An object that conforms to the Order or SignedOrder interface. - * The order you would like to cancel. - * @param cancelTakerTokenAmount The amount (specified in taker tokens) that you would like to cancel. - * @param transactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.contractCallErrorHandler - public async cancelOrderAsync(order: Order|SignedOrder, - cancelTakerTokenAmount: BigNumber, - orderTransactionOpts?: OrderTransactionOpts): Promise { - assert.doesConformToSchema('order', order, schemas.orderSchema); - assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount); - await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper); - - const exchangeInstance = await this._getExchangeContractAsync(); - - const shouldValidate = _.isUndefined(orderTransactionOpts) ? - SHOULD_VALIDATE_BY_DEFAULT : - orderTransactionOpts.shouldValidate; - if (shouldValidate) { - const orderHash = utils.getOrderHashHex(order); - const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - await this._orderValidationUtils.validateCancelOrderThrowIfInvalidAsync( - order, cancelTakerTokenAmount, unavailableTakerTokenAmount); - } - - const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order); - const gas = await exchangeInstance.cancelOrder.estimateGasAsync( - orderAddresses, - orderValues, - cancelTakerTokenAmount, - { - from: order.maker, - }, - ); - const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync( - orderAddresses, - orderValues, - cancelTakerTokenAmount, - { - from: order.maker, - gas, - }, - ); - return txHash; - } - /** - * Batch version of cancelOrderAsync. Atomically cancels multiple orders in a single transaction. - * All orders must be from the same maker. - * @param orderCancellationRequests An array of objects that conform to the OrderCancellationRequest - * interface. - * @param transactionOpts Optional arguments this method accepts. - * @return Transaction hash. - */ - @decorators.contractCallErrorHandler - public async batchCancelOrdersAsync(orderCancellationRequests: OrderCancellationRequest[], - orderTransactionOpts?: OrderTransactionOpts): Promise { - assert.doesConformToSchema('orderCancellationRequests', orderCancellationRequests, - schemas.orderCancellationRequestsSchema); - const exchangeContractAddresses = _.map( - orderCancellationRequests, - orderCancellationRequest => orderCancellationRequest.order.exchangeContractAddress, - ); - assert.hasAtMostOneUniqueValue(exchangeContractAddresses, - ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress); - const makers = _.map(orderCancellationRequests, cancellationRequest => cancellationRequest.order.maker); - assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed); - const maker = makers[0]; - await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper); - const shouldValidate = _.isUndefined(orderTransactionOpts) ? - SHOULD_VALIDATE_BY_DEFAULT : - orderTransactionOpts.shouldValidate; - if (shouldValidate) { - for (const orderCancellationRequest of orderCancellationRequests) { - const orderHash = utils.getOrderHashHex(orderCancellationRequest.order); - const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - await this._orderValidationUtils.validateCancelOrderThrowIfInvalidAsync( - orderCancellationRequest.order, orderCancellationRequest.takerTokenCancelAmount, - unavailableTakerTokenAmount, - ); - } - - } - if (_.isEmpty(orderCancellationRequests)) { - throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - } - const exchangeInstance = await this._getExchangeContractAsync(); - const orderAddressesValuesAndTakerTokenCancelAmounts = _.map(orderCancellationRequests, cancellationRequest => { - return [ - ...ExchangeWrapper._getOrderAddressesAndValues(cancellationRequest.order), - cancellationRequest.takerTokenCancelAmount, - ]; - }); - // We use _.unzip because _.unzip doesn't type check if values have different types :'( - const [orderAddresses, orderValues, cancelTakerTokenAmounts] = - _.unzip(orderAddressesValuesAndTakerTokenCancelAmounts); - const gas = await exchangeInstance.batchCancelOrders.estimateGasAsync( - orderAddresses, - orderValues, - cancelTakerTokenAmounts, - { - from: maker, - }, - ); - const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync( - orderAddresses, - orderValues, - cancelTakerTokenAmounts, - { - from: maker, - gas, - }, - ); - return txHash; - } - /** - * Subscribe to an event type emitted by the Exchange contract. - * @param eventName The exchange contract event you would like to subscribe to. - * @param indexFilterValues An object where the keys are indexed args returned by the event and - * the value is the value you are interested in. E.g `{maker: aUserAddressHex}` - * @param callback Callback that gets called when a log is added/removed - * @return Subscription token used later to unsubscribe - */ - public async subscribeAsync( - eventName: ExchangeEvents, indexFilterValues: IndexedFilterValues, - callback: EventCallback): Promise { - assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents); - assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); - assert.isFunction('callback', callback); - const exchangeContractAddress = await this.getContractAddressAsync(); - const subscriptionToken = this._subscribe( - exchangeContractAddress, eventName, indexFilterValues, artifacts.ExchangeArtifact.abi, callback, - ); - return subscriptionToken; - } - /** - * Cancel a subscription - * @param subscriptionToken Subscription token returned by `subscribe()` - */ - public unsubscribe(subscriptionToken: string): void { - this._unsubscribe(subscriptionToken); - } - /** - * Gets historical logs without creating a subscription - * @param eventName The exchange contract event you would like to subscribe to. - * @param subscriptionOpts Subscriptions options that let you configure the subscription. - * @param indexFilterValues An object where the keys are indexed args returned by the event and - * the value is the value you are interested in. E.g `{_from: aUserAddressHex}` - * @return Array of logs that match the parameters - */ - public async getLogsAsync( - eventName: ExchangeEvents, subscriptionOpts: SubscriptionOpts, indexFilterValues: IndexedFilterValues, - ): Promise>> { - assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents); - assert.doesConformToSchema('subscriptionOpts', subscriptionOpts, schemas.subscriptionOptsSchema); - assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); - const exchangeContractAddress = await this.getContractAddressAsync(); - const logs = await this._getLogsAsync( - exchangeContractAddress, eventName, subscriptionOpts, indexFilterValues, artifacts.ExchangeArtifact.abi, - ); - return logs; - } - /** - * Retrieves the Ethereum address of the Exchange contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the Exchange contract being used. - */ - public async getContractAddressAsync(): Promise { - const exchangeInstance = await this._getExchangeContractAsync(); - const exchangeAddress = exchangeInstance.address; - return exchangeAddress; - } - /** - * Checks if order is still fillable and throws an error otherwise. Useful for orderbook - * pruning where you want to remove stale orders without knowing who the taker will be. - * @param signedOrder An object that conforms to the SignedOrder interface. The - * signedOrder you wish to validate. - * @param opts An object that conforms to the ValidateOrderFillableOpts - * interface. Allows specifying a specific fillTakerTokenAmount - * to validate for. - */ - public async validateOrderFillableOrThrowAsync( - signedOrder: SignedOrder, opts?: ValidateOrderFillableOpts, - ): Promise { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined; - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); - await this._orderValidationUtils.validateOrderFillableOrThrowAsync( - exchangeTradeEmulator, signedOrder, zrxTokenAddress, expectedFillTakerTokenAmount, - ); - } - /** - * Checks if order fill will succeed and throws an error otherwise. - * @param signedOrder An object that conforms to the SignedOrder interface. The - * signedOrder you wish to fill. - * @param fillTakerTokenAmount The total amount of the takerTokens you would like to fill. - * @param takerAddress The user Ethereum address who would like to fill this order. - * Must be available via the supplied Web3.Provider passed to 0x.js. - */ - public async validateFillOrderThrowIfInvalidAsync(signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, - takerAddress: string): Promise { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); - await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); - } - /** - * Checks if cancelling a given order will succeed and throws an informative error if it won't. - * @param order An object that conforms to the Order or SignedOrder interface. - * The order you would like to cancel. - * @param cancelTakerTokenAmount The amount (specified in taker tokens) that you would like to cancel. - */ - public async validateCancelOrderThrowIfInvalidAsync( - order: Order, cancelTakerTokenAmount: BigNumber): Promise { - assert.doesConformToSchema('order', order, schemas.orderSchema); - assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount); - const orderHash = utils.getOrderHashHex(order); - const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - await this._orderValidationUtils.validateCancelOrderThrowIfInvalidAsync( - order, cancelTakerTokenAmount, unavailableTakerTokenAmount); - } - /** - * Checks if calling fillOrKill on a given order will succeed and throws an informative error if it won't. - * @param signedOrder An object that conforms to the SignedOrder interface. The - * signedOrder you wish to fill. - * @param fillTakerTokenAmount The total amount of the takerTokens you would like to fill. - * @param takerAddress The user Ethereum address who would like to fill this order. - * Must be available via the supplied Web3.Provider passed to 0x.js. - */ - public async validateFillOrKillOrderThrowIfInvalidAsync(signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, - takerAddress: string): Promise { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); - const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); - await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); - } - /** - * Checks if rounding error will be > 0.1% when computing makerTokenAmount by doing: - * `(fillTakerTokenAmount * makerTokenAmount) / takerTokenAmount`. - * 0x Protocol does not accept any trades that result in large rounding errors. This means that tokens with few or - * no decimals can only be filled in quantities and ratios that avoid large rounding errors. - * @param fillTakerTokenAmount The amount of the order (in taker tokens baseUnits) that you wish to fill. - * @param takerTokenAmount The order size on the taker side - * @param makerTokenAmount The order size on the maker side - */ - public async isRoundingErrorAsync(fillTakerTokenAmount: BigNumber, - takerTokenAmount: BigNumber, - makerTokenAmount: BigNumber): Promise { - assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - assert.isValidBaseUnitAmount('takerTokenAmount', takerTokenAmount); - assert.isValidBaseUnitAmount('makerTokenAmount', makerTokenAmount); - const exchangeInstance = await this._getExchangeContractAsync(); - const isRoundingError = await exchangeInstance.isRoundingError.callAsync( - fillTakerTokenAmount, takerTokenAmount, makerTokenAmount, - ); - return isRoundingError; - } - /** - * Checks if logs contain LogError, which is emmited by Exchange contract on transaction failure. - * @param logs Transaction logs as returned by `zeroEx.awaitTransactionMinedAsync` - */ - public throwLogErrorsAsErrors(logs: Array|Web3.LogEntry>): void { - const errLog = _.find(logs, { - event: ExchangeEvents.LogError, - }) as LogWithDecodedArgs|undefined; - if (!_.isUndefined(errLog)) { - const logArgs = errLog.args; - const errCode = logArgs.errorId.toNumber(); - const errMessage = this._exchangeContractErrCodesToMsg[errCode]; - throw new Error(errMessage); - } - } - /** - * Returns the ZRX token address used by the exchange contract. - * @return Address of ZRX token - */ - public async getZRXTokenAddressAsync(): Promise { - const exchangeInstance = await this._getExchangeContractAsync(); - const ZRXtokenAddress = await exchangeInstance.ZRX_TOKEN_CONTRACT.callAsync(); - return ZRXtokenAddress; - } - private async _invalidateContractInstancesAsync(): Promise { - this.unsubscribeAll(); - delete this._exchangeContractIfExists; - } - private async _isValidSignatureUsingContractCallAsync(dataHex: string, ecSignature: ECSignature, - signerAddressHex: string): Promise { - assert.isHexString('dataHex', dataHex); - assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema); - assert.isETHAddressHex('signerAddressHex', signerAddressHex); - - const exchangeInstance = await this._getExchangeContractAsync(); - - const isValidSignature = await exchangeInstance.isValidSignature.callAsync( - signerAddressHex, - dataHex, - ecSignature.v, - ecSignature.r, - ecSignature.s, - ); - return isValidSignature; - } - private async _getOrderHashHexUsingContractCallAsync(order: Order|SignedOrder): Promise { - const exchangeInstance = await this._getExchangeContractAsync(); - const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order); - const orderHashHex = await exchangeInstance.getOrderHash.callAsync(orderAddresses, orderValues); - return orderHashHex; - } - private async _getExchangeContractAsync(): Promise { - if (!_.isUndefined(this._exchangeContractIfExists)) { - return this._exchangeContractIfExists; - } - const contractInstance = await this._instantiateContractIfExistsAsync( - artifacts.ExchangeArtifact, this._contractAddressIfExists, - ); - this._exchangeContractIfExists = contractInstance as ExchangeContract; - return this._exchangeContractIfExists; - } - private async _getTokenTransferProxyAddressAsync(): Promise { - const exchangeInstance = await this._getExchangeContractAsync(); - const tokenTransferProxyAddress = await exchangeInstance.TOKEN_TRANSFER_PROXY_CONTRACT.callAsync(); - const tokenTransferProxyAddressLowerCase = tokenTransferProxyAddress.toLowerCase(); - return tokenTransferProxyAddressLowerCase; - } -} diff --git a/src/contract_wrappers/token_registry_wrapper.ts b/src/contract_wrappers/token_registry_wrapper.ts deleted file mode 100644 index 2cc5a9aa0..000000000 --- a/src/contract_wrappers/token_registry_wrapper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import {Web3Wrapper} from '../web3_wrapper'; -import {assert} from '../utils/assert'; -import {Token, TokenRegistryContract, TokenMetadata} from '../types'; -import {constants} from '../utils/constants'; -import {ContractWrapper} from './contract_wrapper'; -import {artifacts} from '../artifacts'; - -/** - * This class includes all the functionality related to interacting with the 0x Token Registry smart contract. - */ -export class TokenRegistryWrapper extends ContractWrapper { - private _tokenRegistryContractIfExists?: TokenRegistryContract; - private _contractAddressIfExists?: string; - constructor(web3Wrapper: Web3Wrapper, contractAddressIfExists?: string) { - super(web3Wrapper); - this._contractAddressIfExists = contractAddressIfExists; - } - /** - * Retrieves all the tokens currently listed in the Token Registry smart contract - * @return An array of objects that conform to the Token interface. - */ - public async getTokensAsync(): Promise { - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - - const addresses = await this.getTokenAddressesAsync(); - const tokenPromises: Array> = _.map( - addresses, - (address: string) => (this.getTokenIfExistsAsync(address)), - ); - const tokens = await Promise.all(tokenPromises); - return tokens as Token[]; - } - /** - * Retrieves all the addresses of the tokens currently listed in the Token Registry smart contract - * @return An array of token addresses. - */ - public async getTokenAddressesAsync(): Promise { - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const addresses = await tokenRegistryContract.getTokenAddresses.callAsync(); - return addresses; - } - /** - * Retrieves a token by address currently listed in the Token Registry smart contract - * @return An object that conforms to the Token interface or undefined if token not found. - */ - public async getTokenIfExistsAsync(address: string): Promise { - assert.isETHAddressHex('address', address); - - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address); - const token = this._createTokenFromMetadata(metadata); - return token; - } - public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise { - assert.isString('symbol', symbol); - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const addressIfExists = await tokenRegistryContract.getTokenAddressBySymbol.callAsync(symbol); - if (addressIfExists === constants.NULL_ADDRESS) { - return undefined; - } - return addressIfExists; - } - public async getTokenAddressByNameIfExistsAsync(name: string): Promise { - assert.isString('name', name); - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const addressIfExists = await tokenRegistryContract.getTokenAddressByName.callAsync(name); - if (addressIfExists === constants.NULL_ADDRESS) { - return undefined; - } - return addressIfExists; - } - public async getTokenBySymbolIfExistsAsync(symbol: string): Promise { - assert.isString('symbol', symbol); - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol); - const token = this._createTokenFromMetadata(metadata); - return token; - } - public async getTokenByNameIfExistsAsync(name: string): Promise { - assert.isString('name', name); - const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const metadata = await tokenRegistryContract.getTokenByName.callAsync(name); - const token = this._createTokenFromMetadata(metadata); - return token; - } - /** - * Retrieves the Ethereum address of the TokenRegistry contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the TokenRegistry contract being used. - */ - public async getContractAddressAsync(): Promise { - const tokenRegistryInstance = await this._getTokenRegistryContractAsync(); - const tokenRegistryAddress = tokenRegistryInstance.address; - return tokenRegistryAddress; - } - private _createTokenFromMetadata(metadata: TokenMetadata): Token|undefined { - if (metadata[0] === constants.NULL_ADDRESS) { - return undefined; - } - const token = { - address: metadata[0], - name: metadata[1], - symbol: metadata[2], - decimals: metadata[3].toNumber(), - }; - return token; - } - private _invalidateContractInstance(): void { - delete this._tokenRegistryContractIfExists; - } - private async _getTokenRegistryContractAsync(): Promise { - if (!_.isUndefined(this._tokenRegistryContractIfExists)) { - return this._tokenRegistryContractIfExists; - } - const contractInstance = await this._instantiateContractIfExistsAsync( - artifacts.TokenRegistryArtifact, this._contractAddressIfExists, - ); - this._tokenRegistryContractIfExists = contractInstance as TokenRegistryContract; - return this._tokenRegistryContractIfExists; - } -} diff --git a/src/contract_wrappers/token_transfer_proxy_wrapper.ts b/src/contract_wrappers/token_transfer_proxy_wrapper.ts deleted file mode 100644 index f81845af9..000000000 --- a/src/contract_wrappers/token_transfer_proxy_wrapper.ts +++ /dev/null @@ -1,60 +0,0 @@ -import * as _ from 'lodash'; -import {Web3Wrapper} from '../web3_wrapper'; -import {ContractWrapper} from './contract_wrapper'; -import {artifacts} from '../artifacts'; -import {TokenTransferProxyContract} from '../types'; - -/** - * This class includes the functionality related to interacting with the TokenTransferProxy contract. - */ -export class TokenTransferProxyWrapper extends ContractWrapper { - private _tokenTransferProxyContractIfExists?: TokenTransferProxyContract; - private _tokenTransferProxyContractAddressFetcher: () => Promise; - constructor(web3Wrapper: Web3Wrapper, tokenTransferProxyContractAddressFetcher: () => Promise) { - super(web3Wrapper); - this._tokenTransferProxyContractAddressFetcher = tokenTransferProxyContractAddressFetcher; - } - /** - * Check if the Exchange contract address is authorized by the TokenTransferProxy contract. - * @param exchangeContractAddress The hex encoded address of the Exchange contract to call. - * @return Whether the exchangeContractAddress is authorized. - */ - public async isAuthorizedAsync(exchangeContractAddress: string): Promise { - const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync(); - const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(exchangeContractAddress); - return isAuthorized; - } - /** - * Get the list of all Exchange contract addresses authorized by the TokenTransferProxy contract. - * @return The list of authorized addresses. - */ - public async getAuthorizedAddressesAsync(): Promise { - const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync(); - const authorizedAddresses = await tokenTransferProxyContractInstance.getAuthorizedAddresses.callAsync(); - return authorizedAddresses; - } - /** - * Retrieves the Ethereum address of the TokenTransferProxy contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the TokenTransferProxy contract being used. - */ - public async getContractAddressAsync(): Promise { - const proxyInstance = await this._getTokenTransferProxyContractAsync(); - const proxyAddress = proxyInstance.address; - return proxyAddress; - } - private _invalidateContractInstance(): void { - delete this._tokenTransferProxyContractIfExists; - } - private async _getTokenTransferProxyContractAsync(): Promise { - if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) { - return this._tokenTransferProxyContractIfExists; - } - const contractAddress = await this._tokenTransferProxyContractAddressFetcher(); - const contractInstance = await this._instantiateContractIfExistsAsync( - artifacts.TokenTransferProxyArtifact, contractAddress, - ); - this._tokenTransferProxyContractIfExists = contractInstance as TokenTransferProxyContract; - return this._tokenTransferProxyContractIfExists; - } -} diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts deleted file mode 100644 index 614ac19d4..000000000 --- a/src/contract_wrappers/token_wrapper.ts +++ /dev/null @@ -1,313 +0,0 @@ -import * as _ from 'lodash'; -import BigNumber from 'bignumber.js'; -import {schemas} from '0x-json-schemas'; -import {Web3Wrapper} from '../web3_wrapper'; -import {assert} from '../utils/assert'; -import {constants} from '../utils/constants'; -import {ContractWrapper} from './contract_wrapper'; -import {AbiDecoder} from '../utils/abi_decoder'; -import {artifacts} from '../artifacts'; -import { - TokenContract, - ZeroExError, - TokenEvents, - IndexedFilterValues, - SubscriptionOpts, - MethodOpts, - LogWithDecodedArgs, - EventCallback, - TokenContractEventArgs, -} from '../types'; - -const ALLOWANCE_TO_ZERO_GAS_AMOUNT = 47275; - -/** - * This class includes all the functionality related to interacting with ERC20 token contracts. - * All ERC20 method calls are supported, along with some convenience methods for getting/setting allowances - * to the 0x Proxy smart contract. - */ -export class TokenWrapper extends ContractWrapper { - public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; - private _tokenContractsByAddress: {[address: string]: TokenContract}; - private _tokenTransferProxyContractAddressFetcher: () => Promise; - constructor(web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, - tokenTransferProxyContractAddressFetcher: () => Promise) { - super(web3Wrapper, abiDecoder); - this._tokenContractsByAddress = {}; - this._tokenTransferProxyContractAddressFetcher = tokenTransferProxyContractAddressFetcher; - } - /** - * Retrieves an owner's ERC20 token balance. - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param ownerAddress The hex encoded user Ethereum address whose balance you would like to check. - * @param methodOpts Optional arguments this method accepts. - * @return The owner's ERC20 token balance in base units. - */ - public async getBalanceAsync(tokenAddress: string, ownerAddress: string, - methodOpts?: MethodOpts): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - - const tokenContract = await this._getTokenContractAsync(tokenAddress); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let balance = await tokenContract.balanceOf.callAsync(ownerAddress, defaultBlock); - // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber - balance = new BigNumber(balance); - return balance; - } - /** - * Sets the spender's allowance to a specified number of baseUnits on behalf of the owner address. - * Equivalent to the ERC20 spec method `approve`. - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param ownerAddress The hex encoded user Ethereum address who would like to set an allowance - * for spenderAddress. - * @param spenderAddress The hex encoded user Ethereum address who will be able to spend the set allowance. - * @param amountInBaseUnits The allowance amount you would like to set. - * @return Transaction hash. - */ - public async setAllowanceAsync(tokenAddress: string, ownerAddress: string, spenderAddress: string, - amountInBaseUnits: BigNumber): Promise { - await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper); - assert.isETHAddressHex('spenderAddress', spenderAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - - const tokenContract = await this._getTokenContractAsync(tokenAddress); - // Hack: for some reason default estimated gas amount causes `base fee exceeds gas limit` exception - // on testrpc. Probably related to https://github.com/ethereumjs/testrpc/issues/294 - // TODO: Debug issue in testrpc and submit a PR, then remove this hack - const networkIdIfExists = await this._web3Wrapper.getNetworkIdIfExistsAsync(); - const gas = networkIdIfExists === constants.TESTRPC_NETWORK_ID ? ALLOWANCE_TO_ZERO_GAS_AMOUNT : undefined; - const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, { - from: ownerAddress, - gas, - }); - return txHash; - } - /** - * Sets the spender's allowance to an unlimited number of baseUnits on behalf of the owner address. - * Equivalent to the ERC20 spec method `approve`. - * Setting an unlimited allowance will lower the gas cost for filling orders involving tokens that forego updating - * allowances set to the max amount (e.g ZRX, WETH) - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param ownerAddress The hex encoded user Ethereum address who would like to set an allowance - * for spenderAddress. - * @param spenderAddress The hex encoded user Ethereum address who will be able to spend the set allowance. - * @return Transaction hash. - */ - public async setUnlimitedAllowanceAsync(tokenAddress: string, ownerAddress: string, - spenderAddress: string): Promise { - const txHash = await this.setAllowanceAsync( - tokenAddress, ownerAddress, spenderAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, - ); - return txHash; - } - /** - * Retrieves the owners allowance in baseUnits set to the spender's address. - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param ownerAddress The hex encoded user Ethereum address whose allowance to spenderAddress - * you would like to retrieve. - * @param spenderAddress The hex encoded user Ethereum address who can spend the allowance you are fetching. - * @param methodOpts Optional arguments this method accepts. - */ - public async getAllowanceAsync(tokenAddress: string, ownerAddress: string, - spenderAddress: string, methodOpts?: MethodOpts): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - - const tokenContract = await this._getTokenContractAsync(tokenAddress); - const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let allowanceInBaseUnits = await tokenContract.allowance.callAsync(ownerAddress, spenderAddress, defaultBlock); - // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber - allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits); - return allowanceInBaseUnits; - } - /** - * Retrieves the owner's allowance in baseUnits set to the 0x proxy contract. - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param ownerAddress The hex encoded user Ethereum address whose proxy contract allowance we are retrieving. - * @param methodOpts Optional arguments this method accepts. - */ - public async getProxyAllowanceAsync(tokenAddress: string, ownerAddress: string, - methodOpts?: MethodOpts): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - - const proxyAddress = await this._getTokenTransferProxyAddressAsync(); - const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts); - return allowanceInBaseUnits; - } - /** - * Sets the 0x proxy contract's allowance to a specified number of a tokens' baseUnits on behalf - * of an owner address. - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param ownerAddress The hex encoded user Ethereum address who is setting an allowance - * for the Proxy contract. - * @param amountInBaseUnits The allowance amount specified in baseUnits. - * @return Transaction hash. - */ - public async setProxyAllowanceAsync(tokenAddress: string, ownerAddress: string, - amountInBaseUnits: BigNumber): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - - const proxyAddress = await this._getTokenTransferProxyAddressAsync(); - const txHash = await this.setAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, amountInBaseUnits); - return txHash; - } - /** - * Sets the 0x proxy contract's allowance to a unlimited number of a tokens' baseUnits on behalf - * of an owner address. - * Setting an unlimited allowance will lower the gas cost for filling orders involving tokens that forego updating - * allowances set to the max amount (e.g ZRX, WETH) - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param ownerAddress The hex encoded user Ethereum address who is setting an allowance - * for the Proxy contract. - * @return Transaction hash. - */ - public async setUnlimitedProxyAllowanceAsync(tokenAddress: string, ownerAddress: string): Promise { - const txHash = await this.setProxyAllowanceAsync( - tokenAddress, ownerAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, - ); - return txHash; - } - /** - * Transfers `amountInBaseUnits` ERC20 tokens from `fromAddress` to `toAddress`. - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param fromAddress The hex encoded user Ethereum address that will send the funds. - * @param toAddress The hex encoded user Ethereum address that will receive the funds. - * @param amountInBaseUnits The amount (specified in baseUnits) of the token to transfer. - * @return Transaction hash. - */ - public async transferAsync(tokenAddress: string, fromAddress: string, toAddress: string, - amountInBaseUnits: BigNumber): Promise { - assert.isETHAddressHex('tokenAddress', tokenAddress); - await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper); - assert.isETHAddressHex('toAddress', toAddress); - assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - - const tokenContract = await this._getTokenContractAsync(tokenAddress); - - const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress); - if (fromAddressBalance.lessThan(amountInBaseUnits)) { - throw new Error(ZeroExError.InsufficientBalanceForTransfer); - } - - const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, { - from: fromAddress, - }); - return txHash; - } - /** - * Transfers `amountInBaseUnits` ERC20 tokens from `fromAddress` to `toAddress`. - * Requires the fromAddress to have sufficient funds and to have approved an allowance of - * `amountInBaseUnits` to `senderAddress`. - * @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed. - * @param fromAddress The hex encoded user Ethereum address whose funds are being sent. - * @param toAddress The hex encoded user Ethereum address that will receive the funds. - * @param senderAddress The hex encoded user Ethereum address whose initiates the fund transfer. The - * `fromAddress` must have set an allowance to the `senderAddress` - * before this call. - * @param amountInBaseUnits The amount (specified in baseUnits) of the token to transfer. - * @return Transaction hash. - */ - public async transferFromAsync(tokenAddress: string, fromAddress: string, toAddress: string, - senderAddress: string, amountInBaseUnits: BigNumber): - Promise { - assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.isETHAddressHex('fromAddress', fromAddress); - assert.isETHAddressHex('toAddress', toAddress); - await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); - assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - - const tokenContract = await this._getTokenContractAsync(tokenAddress); - - const fromAddressAllowance = await this.getAllowanceAsync(tokenAddress, fromAddress, senderAddress); - if (fromAddressAllowance.lessThan(amountInBaseUnits)) { - throw new Error(ZeroExError.InsufficientAllowanceForTransfer); - } - - const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress); - if (fromAddressBalance.lessThan(amountInBaseUnits)) { - throw new Error(ZeroExError.InsufficientBalanceForTransfer); - } - - const txHash = await tokenContract.transferFrom.sendTransactionAsync( - fromAddress, toAddress, amountInBaseUnits, - { - from: senderAddress, - }, - ); - return txHash; - } - /** - * Subscribe to an event type emitted by the Token contract. - * @param tokenAddress The hex encoded address where the ERC20 token is deployed. - * @param eventName The token contract event you would like to subscribe to. - * @param indexFilterValues An object where the keys are indexed args returned by the event and - * the value is the value you are interested in. E.g `{maker: aUserAddressHex}` - * @param callback Callback that gets called when a log is added/removed - * @return Subscription token used later to unsubscribe - */ - public subscribe( - tokenAddress: string, eventName: TokenEvents, indexFilterValues: IndexedFilterValues, - callback: EventCallback): string { - assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); - assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); - assert.isFunction('callback', callback); - const subscriptionToken = this._subscribe( - tokenAddress, eventName, indexFilterValues, artifacts.TokenArtifact.abi, callback, - ); - return subscriptionToken; - } - /** - * Cancel a subscription - * @param subscriptionToken Subscription token returned by `subscribe()` - */ - public unsubscribe(subscriptionToken: string): void { - this._unsubscribe(subscriptionToken); - } - /** - * Gets historical logs without creating a subscription - * @param tokenAddress An address of the token that emmited the logs. - * @param eventName The token contract event you would like to subscribe to. - * @param subscriptionOpts Subscriptions options that let you configure the subscription. - * @param indexFilterValues An object where the keys are indexed args returned by the event and - * the value is the value you are interested in. E.g `{_from: aUserAddressHex}` - * @return Array of logs that match the parameters - */ - public async getLogsAsync( - tokenAddress: string, eventName: TokenEvents, subscriptionOpts: SubscriptionOpts, - indexFilterValues: IndexedFilterValues): Promise>> { - assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); - assert.doesConformToSchema('subscriptionOpts', subscriptionOpts, schemas.subscriptionOptsSchema); - assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); - const logs = await this._getLogsAsync( - tokenAddress, eventName, subscriptionOpts, indexFilterValues, artifacts.TokenArtifact.abi, - ); - return logs; - } - private _invalidateContractInstancesAsync(): void { - this.unsubscribeAll(); - this._tokenContractsByAddress = {}; - } - private async _getTokenContractAsync(tokenAddress: string): Promise { - let tokenContract = this._tokenContractsByAddress[tokenAddress]; - if (!_.isUndefined(tokenContract)) { - return tokenContract; - } - const contractInstance = await this._instantiateContractIfExistsAsync( - artifacts.TokenArtifact, tokenAddress, - ); - tokenContract = contractInstance as TokenContract; - this._tokenContractsByAddress[tokenAddress] = tokenContract; - return tokenContract; - } - private async _getTokenTransferProxyAddressAsync(): Promise { - const tokenTransferProxyContractAddress = await this._tokenTransferProxyContractAddressFetcher(); - return tokenTransferProxyContractAddress; - } -} diff --git a/src/globals.d.ts b/src/globals.d.ts deleted file mode 100644 index cb3800056..000000000 --- a/src/globals.d.ts +++ /dev/null @@ -1,80 +0,0 @@ -/// -/// -declare module 'web3_beta'; -declare module 'chai-bignumber'; -declare module 'dirty-chai'; -declare module 'request-promise-native'; -declare module 'web3-provider-engine'; -declare module 'web3-provider-engine/subproviders/rpc'; - -// HACK: In order to merge the bignumber declaration added by chai-bignumber to the chai Assertion -// interface we must use `namespace` as the Chai definitelyTyped definition does. Since we otherwise -// disallow `namespace`, we disable tslint for the following. -/* tslint:disable */ -declare namespace Chai { - interface Assertion { - bignumber: Assertion; - // HACK: In order to comply with chai-as-promised we make eventually a `PromisedAssertion` not an `Assertion` - eventually: PromisedAssertion; - } -} -/* tslint:enable */ - -declare module '*.json' { - const json: any; - /* tslint:disable */ - export default json; - /* tslint:enable */ -} - -// find-version declarations -declare function findVersions(version: string): string[]; -declare module 'find-versions' { - export = findVersions; -} - -// compare-version declarations -declare function compareVersions(firstVersion: string, secondVersion: string): number; -declare module 'compare-versions' { - export = compareVersions; -} - -// es6-promisify declarations -declare function promisify(original: any, settings?: any): ((...arg: any[]) => Promise); -declare module 'es6-promisify' { - export = promisify; -} - -declare module 'ethereumjs-abi' { - const soliditySHA3: (argTypes: string[], args: any[]) => Buffer; -} - -// truffle-hdwallet-provider declarations -declare module 'truffle-hdwallet-provider' { - import * as Web3 from 'web3'; - class HDWalletProvider implements Web3.Provider { - constructor(mnemonic: string, rpcUrl: string); - public sendAsync( - payload: Web3.JSONRPCRequestPayload, - callback: (err: Error, result: Web3.JSONRPCResponsePayload) => void, - ): void; - } - export = HDWalletProvider; -} - -// abi-decoder declarations -interface DecodedLogArg { -} -interface DecodedLog { - name: string; - events: DecodedLogArg[]; -} -declare module 'abi-decoder' { - import * as Web3 from 'web3'; - const addABI: (abi: Web3.AbiDefinition) => void; - const decodeLogs: (logs: Web3.LogEntry[]) => DecodedLog[]; -} - -declare module 'web3/lib/solidity/coder' { - const decodeParams: (types: string[], data: string) => any[]; -} diff --git a/src/globalsAugment.d.ts b/src/globalsAugment.d.ts deleted file mode 100644 index 60e2312a3..000000000 --- a/src/globalsAugment.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import BigNumber from 'bignumber.js'; - -// HACK: This module overrides the Chai namespace so that we can use BigNumber types inside. -// Source: https://github.com/Microsoft/TypeScript/issues/7352#issuecomment-191547232 -declare global { - // HACK: In order to merge the bignumber declaration added by chai-bignumber to the chai Assertion - // interface we must use `namespace` as the Chai definitelyTyped definition does. Since we otherwise - // disallow `namespace`, we disable tslint for the following. - /* tslint:disable */ - namespace Chai { - interface NumberComparer { - (value: number|BigNumber, message?: string): Assertion; - } - interface NumericComparison { - greaterThan: NumberComparer; - } - } - /* tslint:enable */ - interface DecodedLogArg { - name: string; - value: string|BigNumber; - } -} diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index 1b3e893ba..000000000 --- a/src/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -export {ZeroEx} from './0x'; - -export { - Order, - SignedOrder, - ECSignature, - ZeroExError, - EventCallback, - EventCallbackAsync, - EventCallbackSync, - ExchangeContractErrs, - ContractEvent, - Token, - ExchangeEvents, - TokenEvents, - IndexedFilterValues, - SubscriptionOpts, - BlockParam, - OrderCancellationRequest, - OrderFillRequest, - LogErrorContractEventArgs, - LogCancelContractEventArgs, - LogFillContractEventArgs, - ExchangeContractEventArgs, - TransferContractEventArgs, - ApprovalContractEventArgs, - TokenContractEventArgs, - ContractEventArgs, - ContractEventArg, - Web3Provider, - ZeroExConfig, - TransactionReceipt, - TransactionReceiptWithDecodedLogs, - LogWithDecodedArgs, - MethodOpts, - OrderTransactionOpts, - FilterObject, - LogEvent, - DecodedLogEvent, - EventWatcherCallback, - OnOrderStateChangeCallback, - OrderStateValid, - OrderStateInvalid, - OrderState, -} from './types'; diff --git a/src/order_watcher/event_watcher.ts b/src/order_watcher/event_watcher.ts deleted file mode 100644 index 81529a98c..000000000 --- a/src/order_watcher/event_watcher.ts +++ /dev/null @@ -1,88 +0,0 @@ -import * as Web3 from 'web3'; -import * as _ from 'lodash'; -import {Web3Wrapper} from '../web3_wrapper'; -import { - BlockParamLiteral, - EventCallback, - EventWatcherCallback, - ZeroExError, -} from '../types'; -import {AbiDecoder} from '../utils/abi_decoder'; -import {intervalUtils} from '../utils/interval_utils'; -import {assert} from '../utils/assert'; -import {utils} from '../utils/utils'; - -const DEFAULT_EVENT_POLLING_INTERVAL = 200; - -enum LogEventState { - Removed, - Added, -} - -/* - * The EventWatcher watches for blockchain events at the specified block confirmation - * depth. - */ -export class EventWatcher { - private _web3Wrapper: Web3Wrapper; - private _pollingIntervalMs: number; - private _intervalIdIfExists?: NodeJS.Timer; - private _lastEvents: Web3.LogEntry[] = []; - constructor(web3Wrapper: Web3Wrapper, pollingIntervalMs: undefined|number) { - this._web3Wrapper = web3Wrapper; - this._pollingIntervalMs = _.isUndefined(pollingIntervalMs) ? - DEFAULT_EVENT_POLLING_INTERVAL : - pollingIntervalMs; - } - public subscribe(callback: EventWatcherCallback): void { - assert.isFunction('callback', callback); - if (!_.isUndefined(this._intervalIdIfExists)) { - throw new Error(ZeroExError.SubscriptionAlreadyPresent); - } - this._intervalIdIfExists = intervalUtils.setAsyncExcludingInterval( - this._pollForBlockchainEventsAsync.bind(this, callback), this._pollingIntervalMs, - ); - } - public unsubscribe(): void { - this._lastEvents = []; - if (!_.isUndefined(this._intervalIdIfExists)) { - intervalUtils.clearAsyncExcludingInterval(this._intervalIdIfExists); - delete this._intervalIdIfExists; - } - } - private async _pollForBlockchainEventsAsync(callback: EventWatcherCallback): Promise { - const pendingEvents = await this._getEventsAsync(); - if (pendingEvents.length === 0) { - // HACK: Sometimes when node rebuilds the pending block we get back the empty result. - // We don't want to emit a lot of removal events and bring them back after a couple of miliseconds, - // that's why we just ignore those cases. - return; - } - const removedEvents = _.differenceBy(this._lastEvents, pendingEvents, JSON.stringify); - const newEvents = _.differenceBy(pendingEvents, this._lastEvents, JSON.stringify); - await this._emitDifferencesAsync(removedEvents, LogEventState.Removed, callback); - await this._emitDifferencesAsync(newEvents, LogEventState.Added, callback); - this._lastEvents = pendingEvents; - } - private async _getEventsAsync(): Promise { - const eventFilter = { - fromBlock: BlockParamLiteral.Pending, - toBlock: BlockParamLiteral.Pending, - }; - const events = await this._web3Wrapper.getLogsAsync(eventFilter); - return events; - } - private async _emitDifferencesAsync( - logs: Web3.LogEntry[], logEventState: LogEventState, callback: EventWatcherCallback, - ): Promise { - for (const log of logs) { - const logEvent = { - removed: logEventState === LogEventState.Removed, - ...log, - }; - if (!_.isUndefined(this._intervalIdIfExists)) { - await callback(logEvent); - } - } - } -} diff --git a/src/order_watcher/order_state_watcher.ts b/src/order_watcher/order_state_watcher.ts deleted file mode 100644 index 139f13fdf..000000000 --- a/src/order_watcher/order_state_watcher.ts +++ /dev/null @@ -1,232 +0,0 @@ -import * as _ from 'lodash'; -import {schemas} from '0x-json-schemas'; -import {ZeroEx} from '../0x'; -import {EventWatcher} from './event_watcher'; -import {assert} from '../utils/assert'; -import {utils} from '../utils/utils'; -import {artifacts} from '../artifacts'; -import {AbiDecoder} from '../utils/abi_decoder'; -import {OrderStateUtils} from '../utils/order_state_utils'; -import { - LogEvent, - OrderState, - SignedOrder, - Web3Provider, - BlockParamLiteral, - LogWithDecodedArgs, - ContractEventArgs, - OnOrderStateChangeCallback, - OrderStateWatcherConfig, - ApprovalContractEventArgs, - TransferContractEventArgs, - LogFillContractEventArgs, - LogCancelContractEventArgs, - ExchangeEvents, - TokenEvents, - ZeroExError, -} from '../types'; -import {Web3Wrapper} from '../web3_wrapper'; -import {TokenWrapper} from '../contract_wrappers/token_wrapper'; -import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper'; -import {OrderFilledCancelledLazyStore} from '../stores/order_filled_cancelled_lazy_store'; -import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store'; - -const DEFAULT_NUM_CONFIRMATIONS = 0; - -interface DependentOrderHashes { - [makerAddress: string]: { - [makerToken: string]: Set, - }; -} - -interface OrderByOrderHash { - [orderHash: string]: SignedOrder; -} - -/** - * This class includes all the functionality related to watching a set of orders - * for potential changes in order validity/fillability. The orderWatcher notifies - * the subscriber of these changes so that a final decison can be made on whether - * the order should be deemed invalid. - */ -export class OrderStateWatcher { - private _orderByOrderHash: OrderByOrderHash = {}; - private _dependentOrderHashes: DependentOrderHashes = {}; - private _callbackIfExistsAsync?: OnOrderStateChangeCallback; - private _eventWatcher: EventWatcher; - private _web3Wrapper: Web3Wrapper; - private _abiDecoder: AbiDecoder; - private _orderStateUtils: OrderStateUtils; - private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore; - private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore; - constructor( - web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, token: TokenWrapper, exchange: ExchangeWrapper, - config?: OrderStateWatcherConfig, - ) { - this._abiDecoder = abiDecoder; - this._web3Wrapper = web3Wrapper; - const eventPollingIntervalMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs; - this._eventWatcher = new EventWatcher(web3Wrapper, eventPollingIntervalMs); - this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(token); - this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange); - this._orderStateUtils = new OrderStateUtils( - this._balanceAndProxyAllowanceLazyStore, this._orderFilledCancelledLazyStore, - ); - } - /** - * Add an order to the orderStateWatcher. Before the order is added, it's - * signature is verified. - * @param signedOrder The order you wish to start watching. - */ - public addOrder(signedOrder: SignedOrder): void { - assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); - const orderHash = ZeroEx.getOrderHashHex(signedOrder); - assert.isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker); - this._orderByOrderHash[orderHash] = signedOrder; - this.addToDependentOrderHashes(signedOrder, orderHash); - } - /** - * Removes an order from the orderStateWatcher - * @param orderHash The orderHash of the order you wish to stop watching. - */ - public removeOrder(orderHash: string): void { - assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); - const signedOrder = this._orderByOrderHash[orderHash]; - if (_.isUndefined(signedOrder)) { - return; // noop - } - delete this._orderByOrderHash[orderHash]; - this.removeFromDependentOrderHashes(signedOrder.maker, signedOrder.makerTokenAddress, orderHash); - } - /** - * Starts an orderStateWatcher subscription. The callback will be called every time a watched order's - * backing blockchain state has changed. This is a call-to-action for the caller to re-validate the order. - * @param callback Receives the orderHash of the order that should be re-validated, together - * with all the order-relevant blockchain state needed to re-validate the order. - */ - public subscribe(callback: OnOrderStateChangeCallback): void { - assert.isFunction('callback', callback); - if (!_.isUndefined(this._callbackIfExistsAsync)) { - throw new Error(ZeroExError.SubscriptionAlreadyPresent); - } - this._callbackIfExistsAsync = callback; - this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this)); - } - /** - * Ends an orderStateWatcher subscription. - */ - public unsubscribe(): void { - if (_.isUndefined(this._callbackIfExistsAsync)) { - throw new Error(ZeroExError.SubscriptionNotFound); - } - this._balanceAndProxyAllowanceLazyStore.deleteAll(); - this._orderFilledCancelledLazyStore.deleteAll(); - delete this._callbackIfExistsAsync; - this._eventWatcher.unsubscribe(); - } - private async _onEventWatcherCallbackAsync(log: LogEvent): Promise { - const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop(log); - const isLogDecoded = !_.isUndefined((maybeDecodedLog as LogWithDecodedArgs).event); - if (!isLogDecoded) { - return; // noop - } - const decodedLog = maybeDecodedLog as LogWithDecodedArgs; - let makerToken: string; - let makerAddress: string; - let orderHashesSet: Set; - switch (decodedLog.event) { - case TokenEvents.Approval: - { - // Invalidate cache - const args = decodedLog.args as ApprovalContractEventArgs; - this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner); - // Revalidate orders - makerToken = decodedLog.address; - makerAddress = args._owner; - orderHashesSet = _.get(this._dependentOrderHashes, [makerAddress, makerToken]); - if (!_.isUndefined(orderHashesSet)) { - const orderHashes = Array.from(orderHashesSet); - await this._emitRevalidateOrdersAsync(orderHashes); - } - break; - } - case TokenEvents.Transfer: - { - // Invalidate cache - const args = decodedLog.args as TransferContractEventArgs; - this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from); - this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._to); - // Revalidate orders - makerToken = decodedLog.address; - makerAddress = args._from; - orderHashesSet = _.get(this._dependentOrderHashes, [makerAddress, makerToken]); - if (!_.isUndefined(orderHashesSet)) { - const orderHashes = Array.from(orderHashesSet); - await this._emitRevalidateOrdersAsync(orderHashes); - } - break; - } - case ExchangeEvents.LogFill: - { - // Invalidate cache - const args = decodedLog.args as LogFillContractEventArgs; - this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash); - // Revalidate orders - const orderHash = args.orderHash; - const isOrderWatched = !_.isUndefined(this._orderByOrderHash[orderHash]); - if (isOrderWatched) { - await this._emitRevalidateOrdersAsync([orderHash]); - } - break; - } - case ExchangeEvents.LogCancel: - { - // Invalidate cache - const args = decodedLog.args as LogCancelContractEventArgs; - this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash); - // Revalidate orders - const orderHash = args.orderHash; - const isOrderWatched = !_.isUndefined(this._orderByOrderHash[orderHash]); - if (isOrderWatched) { - await this._emitRevalidateOrdersAsync([orderHash]); - } - break; - } - case ExchangeEvents.LogError: - return; // noop - - default: - throw utils.spawnSwitchErr('decodedLog.event', decodedLog.event); - } - } - private async _emitRevalidateOrdersAsync(orderHashes: string[]): Promise { - for (const orderHash of orderHashes) { - const signedOrder = this._orderByOrderHash[orderHash] as SignedOrder; - // Most of these calls will never reach the network because the data is fetched from stores - // and only updated when cache is invalidated - const orderState = await this._orderStateUtils.getOrderStateAsync(signedOrder); - if (_.isUndefined(this._callbackIfExistsAsync)) { - break; // Unsubscribe was called - } - await this._callbackIfExistsAsync(orderState); - } - } - private addToDependentOrderHashes(signedOrder: SignedOrder, orderHash: string) { - if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker])) { - this._dependentOrderHashes[signedOrder.maker] = {}; - } - if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress])) { - this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress] = new Set(); - } - this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress].add(orderHash); - } - private removeFromDependentOrderHashes(makerAddress: string, makerTokenAddress: string, orderHash: string) { - this._dependentOrderHashes[makerAddress][makerTokenAddress].delete(orderHash); - if (this._dependentOrderHashes[makerAddress][makerTokenAddress].size === 0) { - delete this._dependentOrderHashes[makerAddress][makerTokenAddress]; - } - if (_.isEmpty(this._dependentOrderHashes[makerAddress])) { - delete this._dependentOrderHashes[makerAddress]; - } - } -} diff --git a/src/schemas/zero_ex_config_schema.ts b/src/schemas/zero_ex_config_schema.ts deleted file mode 100644 index 6d4b3ed27..000000000 --- a/src/schemas/zero_ex_config_schema.ts +++ /dev/null @@ -1,23 +0,0 @@ -export const zeroExConfigSchema = { - id: '/ZeroExConfig', - properties: { - gasPrice: {$ref: '/Number'}, - exchangeContractAddress: {$ref: '/Address'}, - tokenRegistryContractAddress: {$ref: '/Address'}, - etherTokenContractAddress: {$ref: '/Address'}, - orderWatcherConfig: { - type: 'object', - properties: { - pollingIntervalMs: { - type: 'number', - minimum: 0, - }, - numConfirmations: { - type: 'number', - minimum: 0, - }, - }, - }, - }, - type: 'object', -}; diff --git a/src/stores/balance_proxy_allowance_lazy_store.ts b/src/stores/balance_proxy_allowance_lazy_store.ts deleted file mode 100644 index c83e61606..000000000 --- a/src/stores/balance_proxy_allowance_lazy_store.ts +++ /dev/null @@ -1,82 +0,0 @@ -import * as _ from 'lodash'; -import * as Web3 from 'web3'; -import {BigNumber} from 'bignumber.js'; -import {TokenWrapper} from '../contract_wrappers/token_wrapper'; -import {BlockParamLiteral} from '../types'; - -/** - * Copy on read store for balances/proxyAllowances of tokens/accounts - */ -export class BalanceAndProxyAllowanceLazyStore { - private token: TokenWrapper; - private balance: { - [tokenAddress: string]: { - [userAddress: string]: BigNumber, - }, - }; - private proxyAllowance: { - [tokenAddress: string]: { - [userAddress: string]: BigNumber, - }, - }; - constructor(token: TokenWrapper) { - this.token = token; - this.balance = {}; - this.proxyAllowance = {}; - } - public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise { - if (_.isUndefined(this.balance[tokenAddress]) || _.isUndefined(this.balance[tokenAddress][userAddress])) { - const methodOpts = { - defaultBlock: BlockParamLiteral.Pending, - }; - const balance = await this.token.getBalanceAsync(tokenAddress, userAddress, methodOpts); - this.setBalance(tokenAddress, userAddress, balance); - } - const cachedBalance = this.balance[tokenAddress][userAddress]; - return cachedBalance; - } - public setBalance(tokenAddress: string, userAddress: string, balance: BigNumber): void { - if (_.isUndefined(this.balance[tokenAddress])) { - this.balance[tokenAddress] = {}; - } - this.balance[tokenAddress][userAddress] = balance; - } - public deleteBalance(tokenAddress: string, userAddress: string): void { - if (!_.isUndefined(this.balance[tokenAddress])) { - delete this.balance[tokenAddress][userAddress]; - if (_.isEmpty(this.balance[tokenAddress])) { - delete this.balance[tokenAddress]; - } - } - } - public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise { - if (_.isUndefined(this.proxyAllowance[tokenAddress]) || - _.isUndefined(this.proxyAllowance[tokenAddress][userAddress])) { - const methodOpts = { - defaultBlock: BlockParamLiteral.Pending, - }; - const proxyAllowance = await this.token.getProxyAllowanceAsync(tokenAddress, userAddress, methodOpts); - this.setProxyAllowance(tokenAddress, userAddress, proxyAllowance); - } - const cachedProxyAllowance = this.proxyAllowance[tokenAddress][userAddress]; - return cachedProxyAllowance; - } - public setProxyAllowance(tokenAddress: string, userAddress: string, proxyAllowance: BigNumber): void { - if (_.isUndefined(this.proxyAllowance[tokenAddress])) { - this.proxyAllowance[tokenAddress] = {}; - } - this.proxyAllowance[tokenAddress][userAddress] = proxyAllowance; - } - public deleteProxyAllowance(tokenAddress: string, userAddress: string): void { - if (!_.isUndefined(this.proxyAllowance[tokenAddress])) { - delete this.proxyAllowance[tokenAddress][userAddress]; - if (_.isEmpty(this.proxyAllowance[tokenAddress])) { - delete this.proxyAllowance[tokenAddress]; - } - } - } - public deleteAll(): void { - this.balance = {}; - this.proxyAllowance = {}; - } -} diff --git a/src/stores/order_filled_cancelled_lazy_store.ts b/src/stores/order_filled_cancelled_lazy_store.ts deleted file mode 100644 index 9d74da096..000000000 --- a/src/stores/order_filled_cancelled_lazy_store.ts +++ /dev/null @@ -1,61 +0,0 @@ -import * as _ from 'lodash'; -import * as Web3 from 'web3'; -import {BigNumber} from 'bignumber.js'; -import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper'; -import {BlockParamLiteral} from '../types'; - -/** - * Copy on read store for filled/cancelled taker amounts - */ -export class OrderFilledCancelledLazyStore { - private exchange: ExchangeWrapper; - private filledTakerAmount: { - [orderHash: string]: BigNumber, - }; - private cancelledTakerAmount: { - [orderHash: string]: BigNumber, - }; - constructor(exchange: ExchangeWrapper) { - this.exchange = exchange; - this.filledTakerAmount = {}; - this.cancelledTakerAmount = {}; - } - public async getFilledTakerAmountAsync(orderHash: string): Promise { - if (_.isUndefined(this.filledTakerAmount[orderHash])) { - const methodOpts = { - defaultBlock: BlockParamLiteral.Pending, - }; - const filledTakerAmount = await this.exchange.getFilledTakerAmountAsync(orderHash, methodOpts); - this.setFilledTakerAmount(orderHash, filledTakerAmount); - } - const cachedFilled = this.filledTakerAmount[orderHash]; - return cachedFilled; - } - public setFilledTakerAmount(orderHash: string, filledTakerAmount: BigNumber): void { - this.filledTakerAmount[orderHash] = filledTakerAmount; - } - public deleteFilledTakerAmount(orderHash: string): void { - delete this.filledTakerAmount[orderHash]; - } - public async getCancelledTakerAmountAsync(orderHash: string): Promise { - if (_.isUndefined(this.cancelledTakerAmount[orderHash])) { - const methodOpts = { - defaultBlock: BlockParamLiteral.Pending, - }; - const cancelledTakerAmount = await this.exchange.getCanceledTakerAmountAsync(orderHash, methodOpts); - this.setCancelledTakerAmount(orderHash, cancelledTakerAmount); - } - const cachedCancelled = this.cancelledTakerAmount[orderHash]; - return cachedCancelled; - } - public setCancelledTakerAmount(orderHash: string, cancelledTakerAmount: BigNumber): void { - this.cancelledTakerAmount[orderHash] = cancelledTakerAmount; - } - public deleteCancelledTakerAmount(orderHash: string): void { - delete this.cancelledTakerAmount[orderHash]; - } - public deleteAll(): void { - this.filledTakerAmount = {}; - this.cancelledTakerAmount = {}; - } -} diff --git a/src/subproviders/empty_wallet_subprovider.ts b/src/subproviders/empty_wallet_subprovider.ts deleted file mode 100644 index 2f260217c..000000000 --- a/src/subproviders/empty_wallet_subprovider.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {JSONRPCPayload} from '../types'; - -/* - * This class implements the web3-provider-engine subprovider interface and returns - * that the provider has no addresses when queried. - * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js - */ -export class EmptyWalletSubProvider { - public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) { - switch (payload.method) { - case 'eth_accounts': - end(null, []); - return; - - default: - next(); - return; - } - } - // Required to implement this method despite not needing it for this subprovider - public setEngine(engine: any) { - // noop - } -} diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index 11683378f..000000000 --- a/src/types.ts +++ /dev/null @@ -1,525 +0,0 @@ -import * as Web3 from 'web3'; -import BigNumber from 'bignumber.js'; - -export enum ZeroExError { - ContractDoesNotExist = 'CONTRACT_DOES_NOT_EXIST', - ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST', - UnhandledError = 'UNHANDLED_ERROR', - UserHasNoAssociatedAddress = 'USER_HAS_NO_ASSOCIATED_ADDRESSES', - InvalidSignature = 'INVALID_SIGNATURE', - ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK', - InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER', - InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER', - InsufficientEthBalanceForDeposit = 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT', - InsufficientWEthBalanceForWithdrawal = 'INSUFFICIENT_WETH_BALANCE_FOR_WITHDRAWAL', - InvalidJump = 'INVALID_JUMP', - OutOfGas = 'OUT_OF_GAS', - NoNetworkId = 'NO_NETWORK_ID', - SubscriptionNotFound = 'SUBSCRIPTION_NOT_FOUND', - SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT', - TransactionMiningTimeout = 'TRANSACTION_MINING_TIMEOUT', -} - -export enum InternalZeroExError { - NoAbiDecoder = 'NO_ABI_DECODER', - ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY', -} - -/** - * Elliptic Curve signature - */ -export interface ECSignature { - v: number; - r: string; - s: string; -} - -export type OrderAddresses = [string, string, string, string, string]; - -export type OrderValues = [BigNumber, BigNumber, BigNumber, - BigNumber, BigNumber, BigNumber]; - -export type LogEvent = Web3.LogEntryEvent; -export type DecodedLogEvent = Web3.DecodedLogEntryEvent; - -export type EventCallbackAsync = (err: null|Error, log?: DecodedLogEvent) => Promise; -export type EventCallbackSync = (err: null|Error, log?: DecodedLogEvent) => void; -export type EventCallback = EventCallbackSync|EventCallbackAsync; - -export type EventWatcherCallbackSync = (log: LogEvent) => void; -export type EventWatcherCallbackAsync = (log: LogEvent) => Promise; -export type EventWatcherCallback = EventWatcherCallbackSync|EventWatcherCallbackAsync; - -export interface ExchangeContract extends Web3.ContractInstance { - isValidSignature: { - callAsync: (signerAddressHex: string, dataHex: string, v: number, r: string, s: string, - txOpts?: TxOpts) => Promise; - }; - ZRX_TOKEN_CONTRACT: { - callAsync: () => Promise; - }; - TOKEN_TRANSFER_PROXY_CONTRACT: { - callAsync: () => Promise; - }; - getUnavailableTakerTokenAmount: { - callAsync: (orderHash: string, defaultBlock?: Web3.BlockParam) => Promise; - }; - isRoundingError: { - callAsync: (takerTokenFillAmount: BigNumber, takerTokenAmount: BigNumber, - makerTokenAmount: BigNumber, txOpts?: TxOpts) => Promise; - }; - fillOrder: { - sendTransactionAsync: (orderAddresses: OrderAddresses, orderValues: OrderValues, - fillTakerTokenAmount: BigNumber, - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - v: number, r: string, s: string, txOpts?: TxOpts) => Promise; - estimateGasAsync: (orderAddresses: OrderAddresses, orderValues: OrderValues, - fillTakerTokenAmount: BigNumber, - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - v: number, r: string, s: string, txOpts?: TxOpts) => Promise; - }; - batchFillOrders: { - sendTransactionAsync: (orderAddresses: OrderAddresses[], orderValues: OrderValues[], - fillTakerTokenAmounts: BigNumber[], - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - v: number[], r: string[], s: string[], txOpts?: TxOpts) => Promise; - estimateGasAsync: (orderAddresses: OrderAddresses[], orderValues: OrderValues[], - fillTakerTokenAmounts: BigNumber[], - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - v: number[], r: string[], s: string[], txOpts?: TxOpts) => Promise; - }; - fillOrdersUpTo: { - sendTransactionAsync: (orderAddresses: OrderAddresses[], orderValues: OrderValues[], - fillTakerTokenAmount: BigNumber, - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - v: number[], r: string[], s: string[], txOpts?: TxOpts) => Promise; - estimateGasAsync: (orderAddresses: OrderAddresses[], orderValues: OrderValues[], - fillTakerTokenAmount: BigNumber, - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - v: number[], r: string[], s: string[], txOpts?: TxOpts) => Promise; - }; - cancelOrder: { - sendTransactionAsync: (orderAddresses: OrderAddresses, orderValues: OrderValues, - cancelTakerTokenAmount: BigNumber, txOpts?: TxOpts) => Promise; - estimateGasAsync: (orderAddresses: OrderAddresses, orderValues: OrderValues, - cancelTakerTokenAmount: BigNumber, - txOpts?: TxOpts) => Promise; - }; - batchCancelOrders: { - sendTransactionAsync: (orderAddresses: OrderAddresses[], orderValues: OrderValues[], - cancelTakerTokenAmounts: BigNumber[], txOpts?: TxOpts) => Promise; - estimateGasAsync: (orderAddresses: OrderAddresses[], orderValues: OrderValues[], - cancelTakerTokenAmounts: BigNumber[], - txOpts?: TxOpts) => Promise; - }; - fillOrKillOrder: { - sendTransactionAsync: (orderAddresses: OrderAddresses, orderValues: OrderValues, - fillTakerTokenAmount: BigNumber, - v: number, r: string, s: string, txOpts?: TxOpts) => Promise; - estimateGasAsync: (orderAddresses: OrderAddresses, orderValues: OrderValues, - fillTakerTokenAmount: BigNumber, - v: number, r: string, s: string, txOpts?: TxOpts) => Promise; - }; - batchFillOrKillOrders: { - sendTransactionAsync: (orderAddresses: OrderAddresses[], orderValues: OrderValues[], - fillTakerTokenAmounts: BigNumber[], - v: number[], r: string[], s: string[], txOpts: TxOpts) => Promise; - estimateGasAsync: (orderAddresses: OrderAddresses[], orderValues: OrderValues[], - fillTakerTokenAmounts: BigNumber[], - v: number[], r: string[], s: string[], txOpts?: TxOpts) => Promise; - }; - filled: { - callAsync: (orderHash: string, defaultBlock?: Web3.BlockParam) => Promise; - }; - cancelled: { - callAsync: (orderHash: string, defaultBlock?: Web3.BlockParam) => Promise; - }; - getOrderHash: { - callAsync: (orderAddresses: OrderAddresses, orderValues: OrderValues) => Promise; - }; -} - -export interface TokenContract extends Web3.ContractInstance { - balanceOf: { - callAsync: (address: string, defaultBlock?: Web3.BlockParam) => Promise; - }; - allowance: { - callAsync: (ownerAddress: string, allowedAddress: string, - defaultBlock?: Web3.BlockParam) => Promise; - }; - transfer: { - sendTransactionAsync: (toAddress: string, amountInBaseUnits: BigNumber, - txOpts?: TxOpts) => Promise; - }; - transferFrom: { - sendTransactionAsync: (fromAddress: string, toAddress: string, amountInBaseUnits: BigNumber, - txOpts?: TxOpts) => Promise; - }; - approve: { - sendTransactionAsync: (proxyAddress: string, amountInBaseUnits: BigNumber, - txOpts?: TxOpts) => Promise; - }; -} - -export interface TokenRegistryContract extends Web3.ContractInstance { - getTokenMetaData: { - callAsync: (address: string) => Promise; - }; - getTokenAddresses: { - callAsync: () => Promise; - }; - getTokenAddressBySymbol: { - callAsync: (symbol: string) => Promise; - }; - getTokenAddressByName: { - callAsync: (name: string) => Promise; - }; - getTokenBySymbol: { - callAsync: (symbol: string) => Promise; - }; - getTokenByName: { - callAsync: (name: string) => Promise; - }; -} - -export interface EtherTokenContract extends Web3.ContractInstance { - deposit: { - sendTransactionAsync: (txOpts: TxOpts) => Promise; - }; - withdraw: { - sendTransactionAsync: (amount: BigNumber, txOpts: TxOpts) => Promise; - }; -} - -export interface TokenTransferProxyContract extends Web3.ContractInstance { - getAuthorizedAddresses: { - callAsync: () => Promise; - }; - authorized: { - callAsync: (address: string) => Promise; - }; -} - -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 - ERROR_FILL_TRUNCATION, // Rounding error too large - ERROR_FILL_BALANCE_ALLOWANCE, // Insufficient balance or allowance for token transfer - ERROR_CANCEL_EXPIRED, // Order has already expired - ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled -} - -export enum ExchangeContractErrs { - OrderFillExpired = 'ORDER_FILL_EXPIRED', - OrderCancelExpired = 'ORDER_CANCEL_EXPIRED', - OrderCancelAmountZero = 'ORDER_CANCEL_AMOUNT_ZERO', - OrderAlreadyCancelledOrFilled = 'ORDER_ALREADY_CANCELLED_OR_FILLED', - OrderFillAmountZero = 'ORDER_FILL_AMOUNT_ZERO', - OrderRemainingFillAmountZero = 'ORDER_REMAINING_FILL_AMOUNT_ZERO', - OrderFillRoundingError = 'ORDER_FILL_ROUNDING_ERROR', - FillBalanceAllowanceError = 'FILL_BALANCE_ALLOWANCE_ERROR', - InsufficientTakerBalance = 'INSUFFICIENT_TAKER_BALANCE', - InsufficientTakerAllowance = 'INSUFFICIENT_TAKER_ALLOWANCE', - InsufficientMakerBalance = 'INSUFFICIENT_MAKER_BALANCE', - InsufficientMakerAllowance = 'INSUFFICIENT_MAKER_ALLOWANCE', - InsufficientTakerFeeBalance = 'INSUFFICIENT_TAKER_FEE_BALANCE', - InsufficientTakerFeeAllowance = 'INSUFFICIENT_TAKER_FEE_ALLOWANCE', - InsufficientMakerFeeBalance = 'INSUFFICIENT_MAKER_FEE_BALANCE', - InsufficientMakerFeeAllowance = 'INSUFFICIENT_MAKER_FEE_ALLOWANCE', - TransactionSenderIsNotFillOrderTaker = 'TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER', - MultipleMakersInSingleCancelBatchDisallowed = 'MULTIPLE_MAKERS_IN_SINGLE_CANCEL_BATCH_DISALLOWED', - InsufficientRemainingFillAmount = 'INSUFFICIENT_REMAINING_FILL_AMOUNT', - MultipleTakerTokensInFillUpToDisallowed = 'MULTIPLE_TAKER_TOKENS_IN_FILL_UP_TO_DISALLOWED', - BatchOrdersMustHaveSameExchangeAddress = 'BATCH_ORDERS_MUST_HAVE_SAME_EXCHANGE_ADDRESS', - BatchOrdersMustHaveAtLeastOneItem = 'BATCH_ORDERS_MUST_HAVE_AT_LEAST_ONE_ITEM', -} - -export type RawLog = Web3.LogEntry; - -export interface ContractEvent { - logIndex: number; - transactionIndex: number; - transactionHash: string; - blockHash: string; - blockNumber: number; - address: string; - type: string; - event: string; - args: ContractEventArgs; -} - -export interface LogFillContractEventArgs { - maker: string; - taker: string; - feeRecipient: string; - makerToken: string; - takerToken: string; - filledMakerTokenAmount: BigNumber; - filledTakerTokenAmount: BigNumber; - paidMakerFee: BigNumber; - paidTakerFee: BigNumber; - tokens: string; - orderHash: string; -} -export interface LogCancelContractEventArgs { - maker: string; - feeRecipient: string; - makerToken: string; - takerToken: string; - cancelledMakerTokenAmount: BigNumber; - cancelledTakerTokenAmount: BigNumber; - tokens: string; - orderHash: string; -} -export interface LogErrorContractEventArgs { - errorId: BigNumber; - orderHash: string; -} -export type ExchangeContractEventArgs = LogFillContractEventArgs|LogCancelContractEventArgs|LogErrorContractEventArgs; -export interface TransferContractEventArgs { - _from: string; - _to: string; - _value: BigNumber; -} -export interface ApprovalContractEventArgs { - _owner: string; - _spender: string; - _value: BigNumber; -} -export type TokenContractEventArgs = TransferContractEventArgs|ApprovalContractEventArgs; -export type ContractEventArgs = ExchangeContractEventArgs|TokenContractEventArgs; -export type ContractEventArg = string|BigNumber; - -export interface Order { - maker: string; - taker: string; - makerFee: BigNumber; - takerFee: BigNumber; - makerTokenAmount: BigNumber; - takerTokenAmount: BigNumber; - makerTokenAddress: string; - takerTokenAddress: string; - salt: BigNumber; - exchangeContractAddress: string; - feeRecipient: string; - expirationUnixTimestampSec: BigNumber; -} - -export interface SignedOrder extends Order { - ecSignature: ECSignature; -} - -// [address, name, symbol, decimals, ipfsHash, swarmHash] -export type TokenMetadata = [string, string, string, BigNumber, string, string]; - -export interface Token { - name: string; - address: string; - symbol: string; - decimals: number; -} - -export interface TxOpts { - from: string; - gas?: number; - value?: BigNumber; -} - -export interface TokenAddressBySymbol { - [symbol: string]: string; -} - -export enum ExchangeEvents { - LogFill = 'LogFill', - LogCancel = 'LogCancel', - LogError = 'LogError', -} - -export enum TokenEvents { - Transfer = 'Transfer', - Approval = 'Approval', -} - -export type ContractEvents = TokenEvents|ExchangeEvents; - -export interface IndexedFilterValues { - [index: string]: ContractEventArg; -} - -export enum BlockParamLiteral { - Latest = 'latest', - Earliest = 'earliest', - Pending = 'pending', -} - -export type BlockParam = BlockParamLiteral|number; - -export interface SubscriptionOpts { - fromBlock: BlockParam; - toBlock: BlockParam; -} - -export type DoneCallback = (err?: Error) => void; - -export interface OrderCancellationRequest { - order: Order|SignedOrder; - takerTokenCancelAmount: BigNumber; -} - -export interface OrderFillRequest { - signedOrder: SignedOrder; - takerTokenFillAmount: BigNumber; -} - -export type AsyncMethod = (...args: any[]) => Promise; - -/** - * We re-export the `Web3.Provider` type specified in the Web3 Typescript typings - * since it is the type of the `provider` argument to the `ZeroEx` constructor. - * It is however a `Web3` library type, not a native `0x.js` type. - */ -export type Web3Provider = Web3.Provider; - -export interface ExchangeContractByAddress { - [address: string]: ExchangeContract; -} - -export interface JSONRPCPayload { - params: any[]; - method: string; -} - -/* - * eventPollingIntervalMs: How often to poll the Ethereum node for new events - */ -export interface OrderStateWatcherConfig { - eventPollingIntervalMs?: number; -} - -/* - * gasPrice: Gas price to use with every transaction - * exchangeContractAddress: The address of an exchange contract to use - * tokenRegistryContractAddress: The address of a token registry contract to use - * etherTokenContractAddress: The address of an ether token contract to use - * orderWatcherConfig: All the configs related to the orderWatcher - */ -export interface ZeroExConfig { - gasPrice?: BigNumber; // Gas price to use with every transaction - exchangeContractAddress?: string; - tokenRegistryContractAddress?: string; - etherTokenContractAddress?: string; - orderWatcherConfig?: OrderStateWatcherConfig; -} - -export enum AbiType { - Function = 'function', - Constructor = 'constructor', - Event = 'event', - Fallback = 'fallback', -} - -export interface DecodedLogArgs { - [argName: string]: ContractEventArg; -} - -export interface LogWithDecodedArgs extends Web3.DecodedLogEntry {} - -export interface TransactionReceiptWithDecodedLogs extends TransactionReceipt { - logs: Array|Web3.LogEntry>; -} - -export interface Artifact { - abi: any; - networks: {[networkId: number]: { - address: string; - }}; -} - -/* - * expectedFillTakerTokenAmount: If specified, the validation method will ensure that the - * supplied order maker has a sufficient allowance/balance to fill this amount of the order's - * takerTokenAmount. If not specified, the validation method ensures that the maker has a sufficient - * allowance/balance to fill the entire remaining order amount. - */ -export interface ValidateOrderFillableOpts { - expectedFillTakerTokenAmount?: BigNumber; -} - -/* - * defaultBlock: The block up to which to query the blockchain state. Setting this to a historical block number - * let's the user query the blockchain's state at an arbitrary point in time. In order for this to work, the - * backing Ethereum node must keep the entire historical state of the chain (e.g setting `--pruning=archive` - * flag when running Parity). - */ -export interface MethodOpts { - defaultBlock?: Web3.BlockParam; -} - -/* - * shouldValidate: Flag indicating whether the library should make attempts to validate a transaction before - * broadcasting it. For example, order has a valid signature, maker has sufficient funds, etc. - */ -export interface OrderTransactionOpts { - shouldValidate: boolean; -} - -export type FilterObject = Web3.FilterObject; - -export enum TradeSide { - Maker = 'maker', - Taker = 'taker', -} - -export enum TransferType { - Trade = 'trade', - Fee = 'fee', -} - -export interface OrderRelevantState { - makerBalance: BigNumber; - makerProxyAllowance: BigNumber; - makerFeeBalance: BigNumber; - makerFeeProxyAllowance: BigNumber; - filledTakerTokenAmount: BigNumber; - canceledTakerTokenAmount: BigNumber; - remainingFillableMakerTokenAmount: BigNumber; -} - -export interface OrderStateValid { - isValid: true; - orderHash: string; - orderRelevantState: OrderRelevantState; -} - -export interface OrderStateInvalid { - isValid: false; - orderHash: string; - error: ExchangeContractErrs; -} - -export type OrderState = OrderStateValid|OrderStateInvalid; - -export type OnOrderStateChangeCallbackSync = (orderState: OrderState) => void; -export type OnOrderStateChangeCallbackAsync = (orderState: OrderState) => Promise; -export type OnOrderStateChangeCallback = OnOrderStateChangeCallbackAsync|OnOrderStateChangeCallbackSync; - -export interface TransactionReceipt { - blockHash: string; - blockNumber: number; - transactionHash: string; - transactionIndex: number; - from: string; - to: string; - status: null|0|1; - cumulativeGasUsed: number; - gasUsed: number; - contractAddress: string|null; - logs: Web3.LogEntry[]; -} diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts deleted file mode 100644 index 840ad9be0..000000000 --- a/src/utils/abi_decoder.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as Web3 from 'web3'; -import * as _ from 'lodash'; -import BigNumber from 'bignumber.js'; -import {AbiType, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes, ContractEventArgs} from '../types'; -import * as SolidityCoder from 'web3/lib/solidity/coder'; - -export class AbiDecoder { - private savedABIs: Web3.AbiDefinition[] = []; - private methodIds: {[signatureHash: string]: Web3.EventAbi} = {}; - constructor(abiArrays: Web3.AbiDefinition[][]) { - _.map(abiArrays, this.addABI.bind(this)); - } - // This method can only decode logs from the 0x & ERC20 smart contracts - public tryToDecodeLogOrNoop( - log: Web3.LogEntry): LogWithDecodedArgs|RawLog { - const methodId = log.topics[0]; - const event = this.methodIds[methodId]; - if (_.isUndefined(event)) { - return log; - } - const logData = log.data; - const decodedParams: DecodedLogArgs = {}; - let dataIndex = 0; - let topicsIndex = 1; - - const nonIndexedInputs = _.filter(event.inputs, input => !input.indexed); - const dataTypes = _.map(nonIndexedInputs, input => input.type); - const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice('0x'.length)); - - _.map(event.inputs, (param: Web3.EventParameter) => { - // Indexed parameters are stored in topics. Non-indexed ones in decodedData - let value = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++]; - if (param.type === SolidityTypes.Address) { - value = this.padZeros(new BigNumber(value).toString(16)); - } else if (param.type === SolidityTypes.Uint256 || - param.type === SolidityTypes.Uint8 || - param.type === SolidityTypes.Uint ) { - value = new BigNumber(value); - } - decodedParams[param.name] = value; - }); - - return { - ...log, - event: event.name, - args: decodedParams, - }; - } - private addABI(abiArray: Web3.AbiDefinition[]): void { - _.map(abiArray, (abi: Web3.AbiDefinition) => { - if (abi.type === AbiType.Event) { - const signature = `${abi.name}(${_.map(abi.inputs, input => input.type).join(',')})`; - const signatureHash = new Web3().sha3(signature); - this.methodIds[signatureHash] = abi; - } - }); - this.savedABIs = this.savedABIs.concat(abiArray); - } - private padZeros(address: string) { - let formatted = address; - if (_.startsWith(formatted, '0x')) { - formatted = formatted.slice(2); - } - - formatted = _.padStart(formatted, 40, '0'); - return `0x${formatted}`; - } -} diff --git a/src/utils/assert.ts b/src/utils/assert.ts deleted file mode 100644 index e5c9439f3..000000000 --- a/src/utils/assert.ts +++ /dev/null @@ -1,101 +0,0 @@ -import * as _ from 'lodash'; -import * as Web3 from 'web3'; -import BigNumber from 'bignumber.js'; -import {SchemaValidator, Schema} from '0x-json-schemas'; -import {Web3Wrapper} from '../web3_wrapper'; -import {signatureUtils} from '../utils/signature_utils'; -import {ECSignature} from '../types'; - -const HEX_REGEX = /^0x[0-9A-F]*$/i; - -export const assert = { - isBigNumber(variableName: string, value: BigNumber): void { - const isBigNumber = _.isObject(value) && (value as any).isBigNumber; - this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value)); - }, - isValidBaseUnitAmount(variableName: string, value: BigNumber) { - assert.isBigNumber(variableName, value); - const hasDecimals = value.decimalPlaces() !== 0; - this.assert( - !hasDecimals, `${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`, - ); - }, - isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string) { - const isValidSignature = signatureUtils.isValidSignature(orderHash, ecSignature, signerAddress); - this.assert(isValidSignature, `Expected order with hash '${orderHash}' to have a valid signature`); - }, - isUndefined(value: any, variableName?: string): void { - this.assert(_.isUndefined(value), this.typeAssertionMessage(variableName, 'undefined', value)); - }, - isString(variableName: string, value: string): void { - this.assert(_.isString(value), this.typeAssertionMessage(variableName, 'string', value)); - }, - isFunction(variableName: string, value: any): void { - this.assert(_.isFunction(value), this.typeAssertionMessage(variableName, 'function', value)); - }, - isHexString(variableName: string, value: string): void { - this.assert(_.isString(value) && HEX_REGEX.test(value), - this.typeAssertionMessage(variableName, 'HexString', value)); - }, - isETHAddressHex(variableName: string, value: string): void { - const web3 = new Web3(); - this.assert(web3.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value)); - this.assert( - web3.isAddress(value) && value.toLowerCase() === value, - `Checksummed addresses are not supported. Convert ${variableName} to lower case before passing`, - ); - }, - doesBelongToStringEnum(variableName: string, value: string, - stringEnum: any /* There is no base type for every string enum */): void { - const doesBelongToStringEnum = !_.isUndefined(stringEnum[value]); - const enumValues = _.keys(stringEnum); - const enumValuesAsStrings = _.map(enumValues, enumValue => `'${enumValue}'`); - const enumValuesAsString = enumValuesAsStrings.join(', '); - assert.assert( - doesBelongToStringEnum, - `Expected ${variableName} to be one of: ${enumValuesAsString}, encountered: ${value}`, - ); - }, - async isSenderAddressAsync(variableName: string, senderAddressHex: string, - web3Wrapper: Web3Wrapper): Promise { - assert.isETHAddressHex(variableName, senderAddressHex); - const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex); - assert.assert(isSenderAddressAvailable, - `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`, - ); - }, - async isUserAddressAvailableAsync(web3Wrapper: Web3Wrapper): Promise { - const availableAddresses = await web3Wrapper.getAvailableAddressesAsync(); - this.assert(!_.isEmpty(availableAddresses), 'No addresses were available on the provided web3 provider'); - }, - hasAtMostOneUniqueValue(value: any[], errMsg: string): void { - this.assert(_.uniq(value).length <= 1, errMsg); - }, - isNumber(variableName: string, value: number): void { - this.assert(_.isFinite(value), this.typeAssertionMessage(variableName, 'number', value)); - }, - isBoolean(variableName: string, value: boolean): void { - this.assert(_.isBoolean(value), this.typeAssertionMessage(variableName, 'boolean', value)); - }, - isWeb3Provider(variableName: string, value: Web3.Provider): void { - const isWeb3Provider = _.isFunction((value as any).send) || _.isFunction((value as any).sendAsync); - this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value)); - }, - doesConformToSchema(variableName: string, value: any, schema: Schema): void { - const schemaValidator = new SchemaValidator(); - const validationResult = schemaValidator.validate(value, schema); - const hasValidationErrors = validationResult.errors.length > 0; - const msg = `Expected ${variableName} to conform to schema ${schema.id} -Encountered: ${JSON.stringify(value, null, '\t')} -Validation errors: ${validationResult.errors.join(', ')}`; - this.assert(!hasValidationErrors, msg); - }, - assert(condition: boolean, message: string): void { - if (!condition) { - throw new Error(message); - } - }, - typeAssertionMessage(variableName: string, type: string, value: any): string { - return `Expected ${variableName} to be of type ${type}, encountered: ${value}`; - }, -}; diff --git a/src/utils/constants.ts b/src/utils/constants.ts deleted file mode 100644 index 3de3f5bc1..000000000 --- a/src/utils/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -import BigNumber from 'bignumber.js'; - -export const constants = { - NULL_ADDRESS: '0x0000000000000000000000000000000000000000', - TESTRPC_NETWORK_ID: 50, - MAX_DIGITS_IN_UNSIGNED_256_INT: 78, - INVALID_JUMP_PATTERN: 'invalid JUMP at', - OUT_OF_GAS_PATTERN: 'out of gas', - UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1), - DEFAULT_BLOCK_POLLING_INTERVAL: 1000, -}; diff --git a/src/utils/decorators.ts b/src/utils/decorators.ts deleted file mode 100644 index ec750b891..000000000 --- a/src/utils/decorators.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as _ from 'lodash'; -import {constants} from './constants'; -import {AsyncMethod, ZeroExError} from '../types'; - -export const decorators = { - /** - * Source: https://stackoverflow.com/a/29837695/3546986 - */ - contractCallErrorHandler(target: object, - key: string|symbol, - descriptor: TypedPropertyDescriptor, - ): TypedPropertyDescriptor { - const originalMethod = (descriptor.value as AsyncMethod); - - // Do not use arrow syntax here. Use a function expression in - // order to use the correct value of `this` in this method - // tslint:disable-next-line:only-arrow-functions - descriptor.value = async function(...args: any[]) { - try { - const result = await originalMethod.apply(this, args); - return result; - } catch (error) { - if (_.includes(error.message, constants.INVALID_JUMP_PATTERN)) { - throw new Error(ZeroExError.InvalidJump); - } - if (_.includes(error.message, constants.OUT_OF_GAS_PATTERN)) { - throw new Error(ZeroExError.OutOfGas); - } - throw error; - } - }; - - return descriptor; - }, -}; diff --git a/src/utils/exchange_transfer_simulator.ts b/src/utils/exchange_transfer_simulator.ts deleted file mode 100644 index 308ef06db..000000000 --- a/src/utils/exchange_transfer_simulator.ts +++ /dev/null @@ -1,88 +0,0 @@ -import * as _ from 'lodash'; -import BigNumber from 'bignumber.js'; -import {ExchangeContractErrs, TradeSide, TransferType, BlockParamLiteral} from '../types'; -import {TokenWrapper} from '../contract_wrappers/token_wrapper'; -import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store'; - -enum FailureReason { - Balance = 'balance', - ProxyAllowance = 'proxyAllowance', -} - -const ERR_MSG_MAPPING = { - [FailureReason.Balance]: { - [TradeSide.Maker]: { - [TransferType.Trade]: ExchangeContractErrs.InsufficientMakerBalance, - [TransferType.Fee]: ExchangeContractErrs.InsufficientMakerFeeBalance, - }, - [TradeSide.Taker]: { - [TransferType.Trade]: ExchangeContractErrs.InsufficientTakerBalance, - [TransferType.Fee]: ExchangeContractErrs.InsufficientTakerFeeBalance, - }, - }, - [FailureReason.ProxyAllowance]: { - [TradeSide.Maker]: { - [TransferType.Trade]: ExchangeContractErrs.InsufficientMakerAllowance, - [TransferType.Fee]: ExchangeContractErrs.InsufficientMakerFeeAllowance, - }, - [TradeSide.Taker]: { - [TransferType.Trade]: ExchangeContractErrs.InsufficientTakerAllowance, - [TransferType.Fee]: ExchangeContractErrs.InsufficientTakerFeeAllowance, - }, - }, -}; - -export class ExchangeTransferSimulator { - private store: BalanceAndProxyAllowanceLazyStore; - private UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber; - constructor(token: TokenWrapper) { - this.store = new BalanceAndProxyAllowanceLazyStore(token); - this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS = token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; - } - /** - * Simulates transferFrom call performed by a proxy - * @param tokenAddress Address of the token to be transferred - * @param from Owner of the transferred tokens - * @param to Recipient of the transferred tokens - * @param amountInBaseUnits The amount of tokens being transferred - * @param tradeSide Is Maker/Taker transferring - * @param transferType Is it a fee payment or a value transfer - */ - public async transferFromAsync(tokenAddress: string, from: string, to: string, - amountInBaseUnits: BigNumber, tradeSide: TradeSide, - transferType: TransferType): Promise { - const balance = await this.store.getBalanceAsync(tokenAddress, from); - const proxyAllowance = await this.store.getProxyAllowanceAsync(tokenAddress, from); - if (proxyAllowance.lessThan(amountInBaseUnits)) { - this.throwValidationError(FailureReason.ProxyAllowance, tradeSide, transferType); - } - if (balance.lessThan(amountInBaseUnits)) { - this.throwValidationError(FailureReason.Balance, tradeSide, transferType); - } - await this.decreaseProxyAllowanceAsync(tokenAddress, from, amountInBaseUnits); - await this.decreaseBalanceAsync(tokenAddress, from, amountInBaseUnits); - await this.increaseBalanceAsync(tokenAddress, to, amountInBaseUnits); - } - private async decreaseProxyAllowanceAsync(tokenAddress: string, userAddress: string, - amountInBaseUnits: BigNumber): Promise { - const proxyAllowance = await this.store.getProxyAllowanceAsync(tokenAddress, userAddress); - if (!proxyAllowance.eq(this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) { - this.store.setProxyAllowance(tokenAddress, userAddress, proxyAllowance.minus(amountInBaseUnits)); - } - } - private async increaseBalanceAsync(tokenAddress: string, userAddress: string, - amountInBaseUnits: BigNumber): Promise { - const balance = await this.store.getBalanceAsync(tokenAddress, userAddress); - this.store.setBalance(tokenAddress, userAddress, balance.plus(amountInBaseUnits)); - } - private async decreaseBalanceAsync(tokenAddress: string, userAddress: string, - amountInBaseUnits: BigNumber): Promise { - const balance = await this.store.getBalanceAsync(tokenAddress, userAddress); - this.store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits)); - } - private throwValidationError(failureReason: FailureReason, tradeSide: TradeSide, - transferType: TransferType): Promise { - const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType]; - throw new Error(errMsg); - } -} diff --git a/src/utils/filter_utils.ts b/src/utils/filter_utils.ts deleted file mode 100644 index e09a95a6e..000000000 --- a/src/utils/filter_utils.ts +++ /dev/null @@ -1,82 +0,0 @@ -import * as _ from 'lodash'; -import * as Web3 from 'web3'; -import * as uuid from 'uuid/v4'; -import * as ethUtil from 'ethereumjs-util'; -import * as jsSHA3 from 'js-sha3'; -import {ContractEvents, IndexedFilterValues, SubscriptionOpts} from '../types'; - -const TOPIC_LENGTH = 32; - -export const filterUtils = { - generateUUID(): string { - return uuid(); - }, - getFilter(address: string, eventName: ContractEvents, - indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi, - subscriptionOpts?: SubscriptionOpts): Web3.FilterObject { - const eventAbi = _.find(abi, {name: eventName}) as Web3.EventAbi; - const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi, eventName); - const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature)); - const topicsForIndexedArgs = filterUtils.getTopicsForIndexedArgs(eventAbi, indexFilterValues); - const topics = [topicForEventSignature, ...topicsForIndexedArgs]; - let filter: Web3.FilterObject = { - address, - topics, - }; - if (!_.isUndefined(subscriptionOpts)) { - filter = { - ...subscriptionOpts, - ...filter, - }; - } - return filter; - }, - getEventSignatureFromAbiByName(eventAbi: Web3.EventAbi, eventName: ContractEvents): string { - const types = _.map(eventAbi.inputs, 'type'); - const signature = `${eventAbi.name}(${types.join(',')})`; - return signature; - }, - getTopicsForIndexedArgs(abi: Web3.EventAbi, indexFilterValues: IndexedFilterValues): Array { - const topics: Array = []; - for (const eventInput of abi.inputs) { - if (!eventInput.indexed) { - continue; - } - if (_.isUndefined(indexFilterValues[eventInput.name])) { - // Null is a wildcard topic in a JSON-RPC call - topics.push(null); - } else { - const value = indexFilterValues[eventInput.name] as string; - const buffer = ethUtil.toBuffer(value); - const paddedBuffer = ethUtil.setLengthLeft(buffer, TOPIC_LENGTH); - const topic = ethUtil.bufferToHex(paddedBuffer); - topics.push(topic); - } - } - return topics; - }, - matchesFilter(log: Web3.LogEntry, filter: Web3.FilterObject): boolean { - if (!_.isUndefined(filter.address) && log.address !== filter.address) { - return false; - } - if (!_.isUndefined(filter.topics)) { - return filterUtils.matchesTopics(log.topics, filter.topics); - } - return true; - }, - matchesTopics(logTopics: string[], filterTopics: Array): boolean { - const matchesTopic = _.zipWith(logTopics, filterTopics, filterUtils.matchesTopic.bind(filterUtils)); - const matchesTopics = _.every(matchesTopic); - return matchesTopics; - }, - matchesTopic(logTopic: string, filterTopic: string[]|string|null): boolean { - if (_.isArray(filterTopic)) { - return _.includes(filterTopic, logTopic); - } - if (_.isString(filterTopic)) { - return filterTopic === logTopic; - } - // null topic is a wildcard - return true; - }, -}; diff --git a/src/utils/interval_utils.ts b/src/utils/interval_utils.ts deleted file mode 100644 index 62b79f2f5..000000000 --- a/src/utils/interval_utils.ts +++ /dev/null @@ -1,20 +0,0 @@ -import * as _ from 'lodash'; - -export const intervalUtils = { - setAsyncExcludingInterval(fn: () => Promise, intervalMs: number) { - let locked = false; - const intervalId = setInterval(async () => { - if (locked) { - return; - } else { - locked = true; - await fn(); - locked = false; - } - }, intervalMs); - return intervalId; - }, - clearAsyncExcludingInterval(intervalId: NodeJS.Timer): void { - clearInterval(intervalId); - }, -}; diff --git a/src/utils/order_state_utils.ts b/src/utils/order_state_utils.ts deleted file mode 100644 index f82601cae..000000000 --- a/src/utils/order_state_utils.ts +++ /dev/null @@ -1,119 +0,0 @@ -import * as _ from 'lodash'; -import * as Web3 from 'web3'; -import BigNumber from 'bignumber.js'; -import { - ExchangeContractErrs, - SignedOrder, - OrderRelevantState, - MethodOpts, - OrderState, - OrderStateValid, - OrderStateInvalid, -} from '../types'; -import {ZeroEx} from '../0x'; -import {TokenWrapper} from '../contract_wrappers/token_wrapper'; -import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper'; -import {utils} from '../utils/utils'; -import {constants} from '../utils/constants'; -import {OrderFilledCancelledLazyStore} from '../stores/order_filled_cancelled_lazy_store'; -import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store'; - -export class OrderStateUtils { - private balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore; - private orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore; - constructor(balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore, - orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore) { - this.balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore; - this.orderFilledCancelledLazyStore = orderFilledCancelledLazyStore; - } - public async getOrderStateAsync(signedOrder: SignedOrder): Promise { - const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder); - const orderHash = ZeroEx.getOrderHashHex(signedOrder); - try { - this.validateIfOrderIsValid(signedOrder, orderRelevantState); - const orderState: OrderStateValid = { - isValid: true, - orderHash, - orderRelevantState, - }; - return orderState; - } catch (err) { - const orderState: OrderStateInvalid = { - isValid: false, - orderHash, - error: err.message, - }; - return orderState; - } - } - public async getOrderRelevantStateAsync(signedOrder: SignedOrder): Promise { - // HACK: We access the private property here but otherwise the interface will be less nice. - // If we pass it from the instantiator - there is no opportunity to get it there - // because JS doesn't support async constructors. - // Moreover - it's cached under the hood so it's equivalent to an async constructor. - const exchange = (this.orderFilledCancelledLazyStore as any).exchange as ExchangeWrapper; - const zrxTokenAddress = await exchange.getZRXTokenAddressAsync(); - const orderHash = ZeroEx.getOrderHashHex(signedOrder); - const makerBalance = await this.balanceAndProxyAllowanceLazyStore.getBalanceAsync( - signedOrder.makerTokenAddress, signedOrder.maker, - ); - const makerProxyAllowance = await this.balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync( - signedOrder.makerTokenAddress, signedOrder.maker, - ); - const makerFeeBalance = await this.balanceAndProxyAllowanceLazyStore.getBalanceAsync( - zrxTokenAddress, signedOrder.maker, - ); - const makerFeeProxyAllowance = await this.balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync( - zrxTokenAddress, signedOrder.maker, - ); - const filledTakerTokenAmount = await this.orderFilledCancelledLazyStore.getFilledTakerAmountAsync(orderHash); - const canceledTakerTokenAmount = await this.orderFilledCancelledLazyStore.getCancelledTakerAmountAsync( - orderHash, - ); - const unavailableTakerTokenAmount = await exchange.getUnavailableTakerAmountAsync(orderHash); - const totalMakerTokenAmount = signedOrder.makerTokenAmount; - const totalTakerTokenAmount = signedOrder.takerTokenAmount; - const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount); - const remainingMakerTokenAmount = remainingTakerTokenAmount.times(totalMakerTokenAmount) - .dividedToIntegerBy(totalTakerTokenAmount); - const fillableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); - const remainingFillableMakerTokenAmount = BigNumber.min(fillableMakerTokenAmount, remainingMakerTokenAmount); - // TODO: Handle edge case where maker token is ZRX with fee - const orderRelevantState = { - makerBalance, - makerProxyAllowance, - makerFeeBalance, - makerFeeProxyAllowance, - filledTakerTokenAmount, - canceledTakerTokenAmount, - remainingFillableMakerTokenAmount, - }; - return orderRelevantState; - } - private validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void { - const unavailableTakerTokenAmount = orderRelevantState.canceledTakerTokenAmount.add( - orderRelevantState.filledTakerTokenAmount, - ); - const availableTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); - if (availableTakerTokenAmount.eq(0)) { - throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero); - } - - if (orderRelevantState.makerBalance.eq(0)) { - throw new Error(ExchangeContractErrs.InsufficientMakerBalance); - } - if (orderRelevantState.makerProxyAllowance.eq(0)) { - throw new Error(ExchangeContractErrs.InsufficientMakerAllowance); - } - if (!signedOrder.makerFee.eq(0)) { - if (orderRelevantState.makerFeeBalance.eq(0)) { - throw new Error(ExchangeContractErrs.InsufficientMakerFeeBalance); - } - if (orderRelevantState.makerFeeProxyAllowance.eq(0)) { - throw new Error(ExchangeContractErrs.InsufficientMakerFeeAllowance); - } - } - // TODO Add linear function solver when maker token is ZRX #badass - // Return the max amount that's fillable - } -} diff --git a/src/utils/order_validation_utils.ts b/src/utils/order_validation_utils.ts deleted file mode 100644 index f03703c4e..000000000 --- a/src/utils/order_validation_utils.ts +++ /dev/null @@ -1,166 +0,0 @@ -import * as _ from 'lodash'; -import BigNumber from 'bignumber.js'; -import {ExchangeContractErrs, SignedOrder, Order, ZeroExError, TradeSide, TransferType} from '../types'; -import {ZeroEx} from '../0x'; -import {TokenWrapper} from '../contract_wrappers/token_wrapper'; -import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper'; -import {utils} from '../utils/utils'; -import {constants} from '../utils/constants'; -import {ExchangeTransferSimulator} from './exchange_transfer_simulator'; - -export class OrderValidationUtils { - private tokenWrapper: TokenWrapper; - private exchangeWrapper: ExchangeWrapper; - constructor(tokenWrapper: TokenWrapper, exchangeWrapper: ExchangeWrapper) { - this.tokenWrapper = tokenWrapper; - this.exchangeWrapper = exchangeWrapper; - } - public async validateOrderFillableOrThrowAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, zrxTokenAddress: string, - expectedFillTakerTokenAmount?: BigNumber): Promise { - const orderHash = utils.getOrderHashHex(signedOrder); - const unavailableTakerTokenAmount = await this.exchangeWrapper.getUnavailableTakerAmountAsync(orderHash); - this.validateRemainingFillAmountNotZeroOrThrow( - signedOrder.takerTokenAmount, unavailableTakerTokenAmount, - ); - this.validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec); - let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); - if (!_.isUndefined(expectedFillTakerTokenAmount)) { - fillTakerTokenAmount = expectedFillTakerTokenAmount; - } - const fillMakerTokenAmount = this.getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerTokenAmount, - ); - await exchangeTradeEmulator.transferFromAsync( - signedOrder.makerTokenAddress, signedOrder.maker, signedOrder.taker, fillMakerTokenAmount, - TradeSide.Maker, TransferType.Trade, - ); - const makerFeeAmount = this.getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerFee, - ); - await exchangeTradeEmulator.transferFromAsync( - zrxTokenAddress, signedOrder.maker, signedOrder.feeRecipient, makerFeeAmount, - TradeSide.Maker, TransferType.Fee, - ); - } - public async validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, takerAddress: string, - zrxTokenAddress: string): Promise { - if (fillTakerTokenAmount.eq(0)) { - throw new Error(ExchangeContractErrs.OrderFillAmountZero); - } - const orderHash = utils.getOrderHashHex(signedOrder); - if (!ZeroEx.isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker)) { - throw new Error(ZeroExError.InvalidSignature); - } - const unavailableTakerTokenAmount = await this.exchangeWrapper.getUnavailableTakerAmountAsync(orderHash); - this.validateRemainingFillAmountNotZeroOrThrow( - signedOrder.takerTokenAmount, unavailableTakerTokenAmount, - ); - if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) { - throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker); - } - this.validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec); - const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); - const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount) ? - remainingTakerTokenAmount : - fillTakerTokenAmount; - await this.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTradeEmulator, signedOrder, filledTakerTokenAmount, takerAddress, zrxTokenAddress, - ); - - const wouldRoundingErrorOccur = await this.exchangeWrapper.isRoundingErrorAsync( - filledTakerTokenAmount, signedOrder.takerTokenAmount, signedOrder.makerTokenAmount, - ); - if (wouldRoundingErrorOccur) { - throw new Error(ExchangeContractErrs.OrderFillRoundingError); - } - return filledTakerTokenAmount; - } - public async validateFillOrKillOrderThrowIfInvalidAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, takerAddress: string, zrxTokenAddress: string): Promise { - const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync( - exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress, - ); - if (filledTakerTokenAmount !== fillTakerTokenAmount) { - throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount); - } - } - public async validateCancelOrderThrowIfInvalidAsync(order: Order, - cancelTakerTokenAmount: BigNumber, - unavailableTakerTokenAmount: BigNumber, - ): Promise { - if (cancelTakerTokenAmount.eq(0)) { - throw new Error(ExchangeContractErrs.OrderCancelAmountZero); - } - if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) { - throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled); - } - const currentUnixTimestampSec = utils.getCurrentUnixTimestamp(); - if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { - throw new Error(ExchangeContractErrs.OrderCancelExpired); - } - } - public async validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, senderAddress: string, zrxTokenAddress: string): Promise { - const fillMakerTokenAmount = this.getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerTokenAmount, - ); - await exchangeTradeEmulator.transferFromAsync( - signedOrder.makerTokenAddress, signedOrder.maker, senderAddress, fillMakerTokenAmount, - TradeSide.Maker, TransferType.Trade, - ); - await exchangeTradeEmulator.transferFromAsync( - signedOrder.takerTokenAddress, senderAddress, signedOrder.maker, fillTakerTokenAmount, - TradeSide.Taker, TransferType.Trade, - ); - const makerFeeAmount = this.getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerFee, - ); - await exchangeTradeEmulator.transferFromAsync( - zrxTokenAddress, signedOrder.maker, signedOrder.feeRecipient, makerFeeAmount, TradeSide.Maker, - TransferType.Fee, - ); - const takerFeeAmount = this.getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.takerFee, - ); - await exchangeTradeEmulator.transferFromAsync( - zrxTokenAddress, senderAddress, signedOrder.feeRecipient, takerFeeAmount, TradeSide.Taker, - TransferType.Fee, - ); - } - private validateRemainingFillAmountNotZeroOrThrow( - takerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber, - ) { - if (takerTokenAmount.eq(unavailableTakerTokenAmount)) { - throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero); - } - } - private validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) { - const currentUnixTimestampSec = utils.getCurrentUnixTimestamp(); - if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { - throw new Error(ExchangeContractErrs.OrderFillExpired); - } - } - private getPartialAmount(numerator: BigNumber, denominator: BigNumber, - target: BigNumber): BigNumber { - const fillMakerTokenAmount = numerator - .mul(target) - .div(denominator) - .round(0); - return fillMakerTokenAmount; - } -} diff --git a/src/utils/signature_utils.ts b/src/utils/signature_utils.ts deleted file mode 100644 index d066f8bf0..000000000 --- a/src/utils/signature_utils.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as ethUtil from 'ethereumjs-util'; -import {ECSignature} from '../types'; - -export const signatureUtils = { - isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean { - const dataBuff = ethUtil.toBuffer(data); - const msgHashBuff = ethUtil.hashPersonalMessage(dataBuff); - try { - const pubKey = ethUtil.ecrecover( - msgHashBuff, - signature.v, - ethUtil.toBuffer(signature.r), - ethUtil.toBuffer(signature.s)); - const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey)); - return retrievedAddress === signerAddress; - } catch (err) { - return false; - } - }, - parseSignatureHexAsVRS(signatureHex: string): ECSignature { - const signatureBuffer = ethUtil.toBuffer(signatureHex); - let v = signatureBuffer[0]; - if (v < 27) { - v += 27; - } - const r = signatureBuffer.slice(1, 33); - const s = signatureBuffer.slice(33, 65); - const ecSignature: ECSignature = { - v, - r: ethUtil.bufferToHex(r), - s: ethUtil.bufferToHex(s), - }; - return ecSignature; - }, - parseSignatureHexAsRSV(signatureHex: string): ECSignature { - const {v, r, s} = ethUtil.fromRpcSig(signatureHex); - const ecSignature: ECSignature = { - v, - r: ethUtil.bufferToHex(r), - s: ethUtil.bufferToHex(s), - }; - return ecSignature; - }, -}; diff --git a/src/utils/utils.ts b/src/utils/utils.ts deleted file mode 100644 index 280f3e979..000000000 --- a/src/utils/utils.ts +++ /dev/null @@ -1,55 +0,0 @@ -import * as _ from 'lodash'; -import * as ethABI from 'ethereumjs-abi'; -import * as ethUtil from 'ethereumjs-util'; -import {Order, SignedOrder, SolidityTypes} from '../types'; -import BigNumber from 'bignumber.js'; -import BN = require('bn.js'); - -export const utils = { - /** - * Converts BigNumber instance to BN - * The only reason we convert to BN is to remain compatible with `ethABI. soliditySHA3` that - * expects values of Solidity type `uint` to be passed as type `BN`. - * We do not use BN anywhere else in the codebase. - */ - bigNumberToBN(value: BigNumber) { - return new BN(value.toString(), 10); - }, - consoleLog(message: string): void { - // 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}`); - }, - getOrderHashHex(order: Order|SignedOrder): string { - const orderParts = [ - {value: order.exchangeContractAddress, type: SolidityTypes.Address}, - {value: order.maker, type: SolidityTypes.Address}, - {value: order.taker, type: SolidityTypes.Address}, - {value: order.makerTokenAddress, type: SolidityTypes.Address}, - {value: order.takerTokenAddress, type: SolidityTypes.Address}, - {value: order.feeRecipient, type: SolidityTypes.Address}, - {value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.Uint256}, - {value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.Uint256}, - {value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.Uint256}, - {value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.Uint256}, - {value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.Uint256}, - {value: utils.bigNumberToBN(order.salt), type: SolidityTypes.Uint256}, - ]; - const types = _.map(orderParts, o => o.type); - const values = _.map(orderParts, o => o.value); - const hashBuff = ethABI.soliditySHA3(types, values); - const hashHex = ethUtil.bufferToHex(hashBuff); - return hashHex; - }, - getCurrentUnixTimestamp(): BigNumber { - return new BigNumber(Date.now() / 1000); - }, -}; diff --git a/src/web3_wrapper.ts b/src/web3_wrapper.ts deleted file mode 100644 index c937f9288..000000000 --- a/src/web3_wrapper.ts +++ /dev/null @@ -1,172 +0,0 @@ -import * as _ from 'lodash'; -import * as Web3 from 'web3'; -import BigNumber from 'bignumber.js'; -import promisify = require('es6-promisify'); -import {ZeroExError, Artifact, TransactionReceipt} from './types'; -import {Contract} from './contract'; - -export class Web3Wrapper { - private web3: Web3; - private defaults: Partial; - private networkIdIfExists?: number; - private jsonRpcRequestId: number; - constructor(provider: Web3.Provider, defaults?: Partial) { - if (_.isUndefined((provider as any).sendAsync)) { - // Web3@1.0 provider doesn't support synchronous http requests, - // so it only has an async `send` method, instead of a `send` and `sendAsync` in web3@0.x.x` - // We re-assign the send method so that Web3@1.0 providers work with 0x.js - (provider as any).sendAsync = (provider as any).send; - } - this.web3 = new Web3(); - this.web3.setProvider(provider); - this.defaults = defaults || {}; - this.jsonRpcRequestId = 0; - } - public setProvider(provider: Web3.Provider) { - delete this.networkIdIfExists; - this.web3.setProvider(provider); - } - public isAddress(address: string): boolean { - return this.web3.isAddress(address); - } - public async isSenderAddressAvailableAsync(senderAddress: string): Promise { - const addresses = await this.getAvailableAddressesAsync(); - return _.includes(addresses, senderAddress); - } - public async getNodeVersionAsync(): Promise { - const nodeVersion = await promisify(this.web3.version.getNode)(); - return nodeVersion; - } - public async getTransactionReceiptAsync(txHash: string): Promise { - const transactionReceipt = await promisify(this.web3.eth.getTransactionReceipt)(txHash); - transactionReceipt.status = this.normalizeTxReceiptStatus(transactionReceipt.status); - return transactionReceipt; - } - public getCurrentProvider(): Web3.Provider { - return this.web3.currentProvider; - } - public async getNetworkIdIfExistsAsync(): Promise { - if (!_.isUndefined(this.networkIdIfExists)) { - return this.networkIdIfExists; - } - - try { - const networkId = await this.getNetworkAsync(); - this.networkIdIfExists = Number(networkId); - return this.networkIdIfExists; - } catch (err) { - return undefined; - } - } - public async getContractInstanceFromArtifactAsync(artifact: Artifact, - address?: string): Promise { - let contractAddress: string; - if (_.isUndefined(address)) { - const networkIdIfExists = await this.getNetworkIdIfExistsAsync(); - if (_.isUndefined(networkIdIfExists)) { - throw new Error(ZeroExError.NoNetworkId); - } - if (_.isUndefined(artifact.networks[networkIdIfExists])) { - throw new Error(ZeroExError.ContractNotDeployedOnNetwork); - } - contractAddress = artifact.networks[networkIdIfExists].address.toLowerCase(); - } else { - contractAddress = address; - } - const doesContractExist = await this.doesContractExistAtAddressAsync(contractAddress); - if (!doesContractExist) { - throw new Error(ZeroExError.ContractDoesNotExist); - } - const contractInstance = this.getContractInstance( - artifact.abi, contractAddress, - ); - return contractInstance; - } - public toWei(ethAmount: BigNumber): BigNumber { - const balanceWei = this.web3.toWei(ethAmount, 'ether'); - return balanceWei; - } - public async getBalanceInWeiAsync(owner: string): Promise { - let balanceInWei = await promisify(this.web3.eth.getBalance)(owner); - balanceInWei = new BigNumber(balanceInWei); - return balanceInWei; - } - public async doesContractExistAtAddressAsync(address: string): Promise { - const code = await promisify(this.web3.eth.getCode)(address); - // Regex matches 0x0, 0x00, 0x in order to accommodate poorly implemented clients - const codeIsEmpty = /^0x0{0,40}$/i.test(code); - return !codeIsEmpty; - } - public async signTransactionAsync(address: string, message: string): Promise { - const signData = await promisify(this.web3.eth.sign)(address, message); - return signData; - } - public async getBlockNumberAsync(): Promise { - const blockNumber = await promisify(this.web3.eth.getBlockNumber)(); - return blockNumber; - } - public async getBlockAsync(blockParam: string|Web3.BlockParam): Promise { - const block = await promisify(this.web3.eth.getBlock)(blockParam); - return block; - } - public async getBlockTimestampAsync(blockParam: string|Web3.BlockParam): Promise { - const {timestamp} = await this.getBlockAsync(blockParam); - return timestamp; - } - public async getAvailableAddressesAsync(): Promise { - const addresses: string[] = await promisify(this.web3.eth.getAccounts)(); - return addresses; - } - public async getLogsAsync(filter: Web3.FilterObject): Promise { - let fromBlock = filter.fromBlock; - if (_.isNumber(fromBlock)) { - fromBlock = this.web3.toHex(fromBlock); - } - let toBlock = filter.toBlock; - if (_.isNumber(toBlock)) { - toBlock = this.web3.toHex(toBlock); - } - const serializedFilter = { - ...filter, - fromBlock, - toBlock, - }; - const payload = { - jsonrpc: '2.0', - id: this.jsonRpcRequestId++, - method: 'eth_getLogs', - params: [serializedFilter], - }; - const logs = await this.sendRawPayloadAsync(payload); - return logs; - } - private getContractInstance(abi: Web3.ContractAbi, address: string): A { - const web3ContractInstance = this.web3.eth.contract(abi).at(address); - const contractInstance = new Contract(web3ContractInstance, this.defaults) as any as A; - return contractInstance; - } - private async getNetworkAsync(): Promise { - const networkId = await promisify(this.web3.version.getNetwork)(); - return networkId; - } - private async sendRawPayloadAsync(payload: Web3.JSONRPCRequestPayload): Promise { - const sendAsync = this.web3.currentProvider.sendAsync.bind(this.web3.currentProvider); - const response = await promisify(sendAsync)(payload); - const result = response.result; - return result; - } - private normalizeTxReceiptStatus(status: undefined|null|string|0|1): null|0|1 { - // Transaction status might have four values - // undefined - Testrpc and other old clients - // null - New clients on old transactions - // number - Parity - // hex - Geth - if (_.isString(status)) { - return this.web3.toDecimal(status) as 0|1; - } else if (_.isUndefined(status)) { - return null; - } else { - return status; - } - } -} -- cgit v1.2.3